├── .gitignore
├── .idea
└── .gitignore
├── IMG_4115.GIF
├── KLineChartLib
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── github
│ │ └── fujianlian
│ │ └── klinechart
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── fujianlian
│ │ │ └── klinechart
│ │ │ ├── BaseKLineChartAdapter.java
│ │ │ ├── BaseKLineChartView.java
│ │ │ ├── DataHelper.java
│ │ │ ├── KLineChartAdapter.java
│ │ │ ├── KLineChartView.java
│ │ │ ├── KLineEntity.java
│ │ │ ├── ScrollAndScaleView.java
│ │ │ ├── base
│ │ │ ├── IAdapter.java
│ │ │ ├── IChartDraw.java
│ │ │ ├── IDateTimeFormatter.java
│ │ │ └── IValueFormatter.java
│ │ │ ├── draw
│ │ │ ├── KDJDraw.java
│ │ │ ├── MACDDraw.java
│ │ │ ├── MainDraw.java
│ │ │ ├── RSIDraw.java
│ │ │ ├── Status.java
│ │ │ ├── VolumeDraw.java
│ │ │ └── WRDraw.java
│ │ │ ├── entity
│ │ │ ├── ICandle.java
│ │ │ ├── IKDJ.java
│ │ │ ├── IKLine.java
│ │ │ ├── IMACD.java
│ │ │ ├── IRSI.java
│ │ │ ├── IVolume.java
│ │ │ ├── IWR.java
│ │ │ └── OrderEntity.java
│ │ │ ├── formatter
│ │ │ ├── BigValueFormatter.java
│ │ │ ├── DateFormatter.java
│ │ │ ├── TimeFormatter.java
│ │ │ └── ValueFormatter.java
│ │ │ └── utils
│ │ │ ├── Constants.java
│ │ │ ├── DateUtil.java
│ │ │ └── ViewUtil.java
│ └── res
│ │ ├── drawable
│ │ ├── ic_down_order.png
│ │ ├── ic_point_kline.png
│ │ ├── ic_start_time.png
│ │ ├── ic_stop_time.png
│ │ ├── ic_target_normal.png
│ │ ├── ic_target_pressed.png
│ │ ├── ic_up.png
│ │ ├── selector_button_target.xml
│ │ └── shape_rectangle_with.xml
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── github
│ └── fujianlian
│ └── klinechart
│ └── ExampleUnitTest.java
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── ibm.json
│ ├── java
│ └── com
│ │ └── vincent
│ │ └── story
│ │ ├── DataBean.java
│ │ ├── DataRequest.java
│ │ ├── MainActivity.java
│ │ ├── adapter
│ │ └── DateCycleAdapter.java
│ │ └── app
│ │ ├── ActivityStack.java
│ │ └── MyApp.java
│ └── res
│ ├── layout
│ ├── activity_main.xml
│ └── item_tv_layout.xml
│ ├── mipmap-xhdpi
│ ├── ic_launcher_round.png
│ ├── ic_no_image.png
│ └── icon_temp_load.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher_round.png
│ ├── values-sw1024dp
│ └── dimens.xml
│ ├── values-sw1280dp
│ └── dimens.xml
│ ├── values-sw1365dp
│ └── dimens.xml
│ ├── values-sw384dp
│ └── dimens.xml
│ ├── values-sw392dp
│ └── dimens.xml
│ ├── values-sw400dp
│ └── dimens.xml
│ ├── values-sw410dp
│ └── dimens.xml
│ ├── values-sw411dp
│ └── dimens.xml
│ ├── values-sw432dp
│ └── dimens.xml
│ ├── values-sw480dp
│ └── dimens.xml
│ ├── values-sw533dp
│ └── dimens.xml
│ ├── values-sw592dp
│ └── dimens.xml
│ ├── values-sw600dp
│ └── dimens.xml
│ ├── values-sw640dp
│ └── dimens.xml
│ ├── values-sw662dp
│ └── dimens.xml
│ ├── values-sw720dp
│ └── dimens.xml
│ ├── values-sw768dp
│ └── dimens.xml
│ ├── values-sw800dp
│ └── dimens.xml
│ ├── values-sw811dp
│ └── dimens.xml
│ ├── values-sw820dp
│ └── dimens.xml
│ ├── values-sw960dp
│ └── dimens.xml
│ ├── values-sw961dp
│ └── dimens.xml
│ ├── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ ├── filepaths.xml
│ └── network_security_config.xml
├── build.gradle
├── config.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── img1.jpg
├── img2.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 | *.aab
5 |
6 | # Files for the ART/Dalvik VM
7 | *.dex
8 |
9 | # Java class files
10 | *.class
11 |
12 | # Generated files
13 | bin/
14 | gen/
15 | out/
16 |
17 | # Gradle files
18 | .gradle/
19 | build/
20 |
21 | # Local configuration file (sdk path, etc)
22 | local.properties
23 |
24 | # Proguard folder generated by Eclipse
25 | proguard/
26 |
27 | # Log Files
28 | *.log
29 |
30 | # Android Studio Navigation editor temp files
31 | .navigation/
32 |
33 | # Android Studio captures folder
34 | captures/
35 |
36 | # IntelliJ
37 | *.iml
38 | .idea/workspace.xml
39 | .idea/tasks.xml
40 | .idea/gradle.xml
41 | .idea/assetWizardSettings.xml
42 | .idea/dictionaries
43 | .idea/libraries
44 | .idea/caches
45 |
46 | # Keystore files
47 | # Uncomment the following lines if you do not want to check your keystore files in.
48 | #*.jks
49 | #*.keystore
50 |
51 | # External native build folder generated in Android Studio 2.2 and later
52 | .externalNativeBuild
53 |
54 | # Google Services (e.g. APIs or Firebase)
55 | # google-services.json
56 |
57 | # Freeline
58 | freeline.py
59 | freeline/
60 | freeline_project_description.json
61 |
62 | # fastlane
63 | fastlane/report.xml
64 | fastlane/Preview.html
65 | fastlane/screenshots
66 | fastlane/test_output
67 | fastlane/readme.md
68 |
69 | # Version control
70 | vcs.xml
71 |
72 | # lint
73 | lint/intermediates/
74 | lint/generated/
75 | lint/outputs/
76 | lint/tmp/
77 | # lint/reports/
78 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/IMG_4115.GIF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/IMG_4115.GIF
--------------------------------------------------------------------------------
/KLineChartLib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/KLineChartLib/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 27
5 |
6 | defaultConfig {
7 | minSdkVersion 16
8 | targetSdkVersion 27
9 | versionCode 1
10 | versionName "1.0"
11 |
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 |
14 | }
15 |
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 |
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: 'libs', include: ['*.jar'])
27 |
28 | implementation 'com.android.support:appcompat-v7:27.1.1'
29 | testImplementation 'junit:junit:4.12'
30 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
31 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/KLineChartLib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/KLineChartLib/src/androidTest/java/com/github/fujianlian/klinechart/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.github.fujianlian.klinechart.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/BaseKLineChartAdapter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 | import android.database.DataSetObservable;
4 | import android.database.DataSetObserver;
5 |
6 | import com.github.fujianlian.klinechart.base.IAdapter;
7 |
8 | /**
9 | * k线图的数据适配器
10 | * Created by tifezh on 2016/6/9.
11 | */
12 |
13 | public abstract class BaseKLineChartAdapter implements IAdapter {
14 |
15 | private final DataSetObservable mDataSetObservable = new DataSetObservable();
16 |
17 | @Override
18 | public void notifyDataSetChanged() {
19 | if (getCount() > 0) {
20 | mDataSetObservable.notifyChanged();
21 | } else {
22 | mDataSetObservable.notifyInvalidated();
23 | }
24 | }
25 |
26 |
27 | @Override
28 | public void registerDataSetObserver(DataSetObserver observer) {
29 | mDataSetObservable.registerObserver(observer);
30 | }
31 |
32 | @Override
33 | public void unregisterDataSetObserver(DataSetObserver observer) {
34 | mDataSetObservable.unregisterObserver(observer);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/DataHelper.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 |
4 | import android.util.Log;
5 |
6 | import com.github.fujianlian.klinechart.utils.Constants;
7 | import com.github.fujianlian.klinechart.utils.DateUtil;
8 |
9 | import java.util.List;
10 |
11 |
12 |
13 | import static com.github.fujianlian.klinechart.utils.Constants.RANG_ITEM;
14 |
15 | /**
16 | * 数据辅助类 计算macd rsi等
17 | * Created by tifezh on 2016/11/26.
18 | */
19 | public class DataHelper {
20 |
21 | /**
22 | * 计算RSI
23 | *
24 | * @param dataList
25 | */
26 | static void calculateRSI(List dataList) {
27 | Float rsi;
28 | float rsiABSEma = 0;
29 | float rsiMaxEma = 0;
30 | for (int i = 0; i < dataList.size(); i++) {
31 | KLineEntity point = dataList.get(i);
32 | final float closePrice = point.getClosePrice();
33 | if (i == 0) {
34 | rsi = 0f;
35 | rsiABSEma = 0;
36 | rsiMaxEma = 0;
37 | } else {
38 | float Rmax = Math.max(0, closePrice - dataList.get(i - 1).getClosePrice());
39 | float RAbs = Math.abs(closePrice - dataList.get(i - 1).getClosePrice());
40 |
41 | rsiMaxEma = (Rmax + (14f - 1) * rsiMaxEma) / 14f;
42 | rsiABSEma = (RAbs + (14f - 1) * rsiABSEma) / 14f;
43 | rsi = (rsiMaxEma / rsiABSEma) * 100;
44 | }
45 | if (i < 13) {
46 | rsi = 0f;
47 | }
48 | if (rsi.isNaN())
49 | rsi = 0f;
50 | point.rsi = rsi;
51 | }
52 | }
53 |
54 | /**
55 | * 计算kdj
56 | *
57 | * @param dataList
58 | */
59 | static void calculateKDJ(List dataList) {
60 | float k = 0;
61 | float d = 0;
62 | for (int i = 0; i < dataList.size(); i++) {
63 | KLineEntity point = dataList.get(i);
64 | final float closePrice = point.getClosePrice();
65 | int startIndex = i - 13;
66 | if (startIndex < 0) {
67 | startIndex = 0;
68 | }
69 | float max14 = Float.MIN_VALUE;
70 | float min14 = Float.MAX_VALUE;
71 | for (int index = startIndex; index <= i; index++) {
72 | if (dataList.get(index) == null)
73 | return;
74 | max14 = Math.max(max14, dataList.get(index).getHighPrice());
75 | min14 = Math.min(min14, dataList.get(index).getLowPrice());
76 | }
77 | Float rsv = 100f * (closePrice - min14) / (max14 - min14);
78 | if (rsv.isNaN()) {
79 | rsv = 0f;
80 | }
81 | if (i == 0) {
82 | k = 50;
83 | d = 50;
84 | } else {
85 | k = (rsv + 2f * k) / 3f;
86 | d = (k + 2f * d) / 3f;
87 | }
88 | if (i < 13) {
89 | point.k = 0;
90 | point.d = 0;
91 | point.j = 0;
92 | } else if (i == 13 || i == 14) {
93 | point.k = k;
94 | point.d = 0;
95 | point.j = 0;
96 | } else {
97 | point.k = k;
98 | point.d = d;
99 | point.j = 3f * k - 2 * d;
100 | }
101 | }
102 |
103 | }
104 |
105 | /**
106 | * 计算wr
107 | *
108 | * @param dataList
109 | */
110 | static void calculateWR(List dataList) {
111 | Float r;
112 | for (int i = 0; i < dataList.size(); i++) {
113 | KLineEntity point = dataList.get(i);
114 | int startIndex = i - 14;
115 | if (startIndex < 0) {
116 | startIndex = 0;
117 | }
118 | float max14 = Float.MIN_VALUE;
119 | float min14 = Float.MAX_VALUE;
120 | for (int index = startIndex; index <= i; index++) {
121 |
122 | max14 = Math.max(max14, dataList.get(index).getHighPrice());
123 | min14 = Math.min(min14, dataList.get(index).getLowPrice());
124 | }
125 | if (i < 13) {
126 | point.r = -10;
127 | } else {
128 | r = -100 * (max14 - dataList.get(i).getClosePrice()) / (max14 - min14);
129 | if (r.isNaN()) {
130 | point.r = 0;
131 | } else {
132 | point.r = r;
133 | }
134 | }
135 | }
136 |
137 | }
138 |
139 | /**
140 | * 计算macd
141 | *
142 | * @param dataList
143 | */
144 | static void calculateMACD(List dataList) {
145 | float ema12 = 0;
146 | float ema26 = 0;
147 | float dif = 0;
148 | float dea = 0;
149 | float macd = 0;
150 |
151 | for (int i = 0; i < dataList.size(); i++) {
152 | KLineEntity point = dataList.get(i);
153 | final float closePrice = point.getClosePrice();
154 | if (i == 0) {
155 | ema12 = closePrice;
156 | ema26 = closePrice;
157 | } else {
158 | // EMA(12) = 前一日EMA(12) X 11/13 + 今日收盘价 X 2/13
159 | ema12 = ema12 * 11f / 13f + closePrice * 2f / 13f;
160 | // EMA(26) = 前一日EMA(26) X 25/27 + 今日收盘价 X 2/27
161 | ema26 = ema26 * 25f / 27f + closePrice * 2f / 27f;
162 | }
163 | // DIF = EMA(12) - EMA(26) 。
164 | // 今日DEA = (前一日DEA X 8/10 + 今日DIF X 2/10)
165 | // 用(DIF-DEA)*2即为MACD柱状图。
166 | dif = ema12 - ema26;
167 | dea = dea * 8f / 10f + dif * 2f / 10f;
168 | macd = (dif - dea) * 2f;
169 | point.dif = dif;
170 | point.dea = dea;
171 | point.macd = macd;
172 | }
173 |
174 | }
175 |
176 | /**
177 | * 计算 BOLL 需要在计算ma之后进行
178 | *
179 | * @param dataList
180 | */
181 | static void calculateBOLL(List dataList) {
182 | for (int i = 0; i < dataList.size(); i++) {
183 | KLineEntity point = dataList.get(i);
184 | if (i < 19) {
185 | point.mb = 0;
186 | point.up = 0;
187 | point.dn = 0;
188 | } else {
189 | int n = 20;
190 | float md = 0;
191 | for (int j = i - n + 1; j <= i; j++) {
192 | float c = dataList.get(j).getClosePrice();
193 | float m = point.getMA20Price();
194 | float value = c - m;
195 | md += value * value;
196 | }
197 | md = md / (n - 1);
198 | md = (float) Math.sqrt(md);
199 | point.mb = point.getMA20Price();
200 | point.up = point.mb + 2f * md;
201 | point.dn = point.mb - 2f * md;
202 | }
203 | }
204 |
205 | }
206 |
207 | /**
208 | * @param dataList
209 | */
210 | static void calculateSAR(List dataList) {
211 |
212 | //SAR指标py代码
213 | //def psar(barsdata, iaf = 0.02, maxaf = 0.2):
214 | // length = len(barsdata)
215 | // dates = list(barsdata['Date'])
216 | // high = list(barsdata['High'])
217 | // low = list(barsdata['Low'])
218 | // close = list(barsdata['Close'])
219 | // psar = close[0:len(close)]
220 | // psarbull = [None] * length
221 | // psarbear = [None] * length
222 | // bull = True
223 | // af = iaf
224 | // ep = low[0]
225 | // hp = high[0]
226 | // lp = low[0]
227 | //
228 | // for i in range(2,length):
229 | // if bull:
230 | // psar[i] = psar[i - 1] + af * (hp - psar[i - 1])
231 | // else:
232 | // psar[i] = psar[i - 1] + af * (lp - psar[i - 1])
233 | //
234 | // reverse = False
235 | //
236 | // if bull:
237 | // if low[i] < psar[i]:
238 | // bull = False
239 | // reverse = True
240 | // psar[i] = hp
241 | // lp = low[i]
242 | // af = iaf
243 | // else:
244 | // if high[i] > psar[i]:
245 | // bull = True
246 | // reverse = True
247 | // psar[i] = lp
248 | // hp = high[i]
249 | // af = iaf
250 | //
251 | // if not reverse:
252 | // if bull:
253 | // if high[i] > hp:
254 | // hp = high[i]
255 | // af = min(af + iaf, maxaf)
256 | // if low[i - 1] < psar[i]:
257 | // psar[i] = low[i - 1]
258 | // if low[i - 2] < psar[i]:
259 | // psar[i] = low[i - 2]
260 | // else:
261 | // if low[i] < lp:
262 | // lp = low[i]
263 | // af = min(af + iaf, maxaf)
264 | // if high[i - 1] > psar[i]:
265 | // psar[i] = high[i - 1]
266 | // if high[i - 2] > psar[i]:
267 | // psar[i] = high[i - 2]
268 | //
269 | // if bull:
270 | // psarbull[i] = psar[i]
271 | // else:
272 | // psarbear[i] = psar[i]
273 | //
274 | // return {"dates":dates, "high":high, "low":low, "close":close, "psar":psar, "psarbear":psarbear, "psarbull":psarbull}
275 | //
276 | //这段代码有点问题 需要修改下才能使用
277 |
278 | for (int i = 0; i < dataList.size(); i++) {
279 | KLineEntity point = dataList.get(i);
280 |
281 | }
282 |
283 | }
284 |
285 | /**
286 | * 计算ma
287 | *
288 | * @param dataList
289 | */
290 | static void calculateMA(List dataList) {
291 | float ma5 = 0;
292 | float ma10 = 0;
293 | float ma20 = 0;
294 | float ma30 = 0;
295 | float ma60 = 0;
296 |
297 | for (int i = 0; i < dataList.size(); i++) {
298 | KLineEntity point = dataList.get(i);
299 | final float closePrice = point.getClosePrice();
300 |
301 | ma5 += closePrice;
302 | ma10 += closePrice;
303 | ma20 += closePrice;
304 | ma30 += closePrice;
305 | ma60 += closePrice;
306 | if (i == 4) {
307 | point.MA5Price = ma5 / 5f;
308 | } else if (i >= 5) {
309 | ma5 -= dataList.get(i - 5).getClosePrice();
310 | point.MA5Price = ma5 / 5f;
311 | } else {
312 | point.MA5Price = 0f;
313 | }
314 | if (i == 9) {
315 | point.MA10Price = ma10 / 10f;
316 | } else if (i >= 10) {
317 | ma10 -= dataList.get(i - 10).getClosePrice();
318 | point.MA10Price = ma10 / 10f;
319 | } else {
320 | point.MA10Price = 0f;
321 | }
322 | if (i == 19) {
323 | point.MA20Price = ma20 / 20f;
324 | } else if (i >= 20) {
325 | ma20 -= dataList.get(i - 20).getClosePrice();
326 | point.MA20Price = ma20 / 20f;
327 | } else {
328 | point.MA20Price = 0f;
329 | }
330 | if (i == 29) {
331 | point.MA30Price = ma30 / 30f;
332 | } else if (i >= 30) {
333 | ma30 -= dataList.get(i - 30).getClosePrice();
334 | point.MA30Price = ma30 / 30f;
335 | } else {
336 | point.MA30Price = 0f;
337 | }
338 | if (i == 59) {
339 | point.MA60Price = ma60 / 60f;
340 | } else if (i >= 60) {
341 | ma60 -= dataList.get(i - 60).getClosePrice();
342 | point.MA60Price = ma60 / 60f;
343 | } else {
344 | point.MA60Price = 0f;
345 | }
346 | }
347 | }
348 |
349 | /**
350 | * 计算MA BOLL RSI KDJ MACD
351 | *
352 | * @param dataList
353 | */
354 | public static void calculate(List dataList) {
355 | calculateMA(dataList);
356 | // calculateSAR(dataList);
357 | calculateMACD(dataList);
358 | calculateBOLL(dataList);
359 | calculateRSI(dataList);
360 | calculateKDJ(dataList);
361 | calculateWR(dataList);
362 | calculateVolumeMA(dataList);
363 | }
364 |
365 | private static String[] periods = new String[]{Constants.ONE_MINUTE, Constants.FIVE_MINUTE, Constants.FIFTEEN_MINUTE,
366 | Constants.THIRTY_MINUTE, Constants.SIXTY_MINUTE, Constants.ONE_DAY, Constants.ONE_WEEK, Constants.ONE_MON};
367 |
368 | private static String[] optionPeriods = new String[]{Constants.FIVE_SECOND};
369 |
370 | public static String[] getPeriods(String currentType) {
371 | if (currentType.equals("2")) {
372 | return periods;
373 | } else {
374 | return optionPeriods;
375 | }
376 | }
377 |
378 | /**
379 | * 计算最后二十条数据时间
380 | *
381 | * @param entries
382 | */
383 | public static void calculateEndData(List entries, int choosePosition, String currentType, float openPirce) {
384 | // DateUtil.DatePattern datePattern;
385 | if (entries.size() == 0)
386 | return;
387 | String time = entries.get(entries.size() - (Constants.RANG_ITEM + 1)).getTimestamp();//时间戳
388 | for (int i = entries.size() - (Constants.RANG_ITEM + 1); i < entries.size(); i++) {
389 | Long newTime = Long.valueOf(time) + DataHelper.getT(getPeriods(currentType)[choosePosition]) * (i - (entries.size() - (Constants.RANG_ITEM + 1)));
390 | entries.get(i).setDate(DateUtil.getStrTime(newTime + "", getDatePattern(getPeriods(currentType)[choosePosition])));
391 | entries.get(i).setTimestamp(newTime + "");
392 | entries.get(i).setOpen(openPirce);
393 | }
394 | }
395 |
396 |
397 | public static DateUtil.DatePattern getDatePattern(String time) {
398 |
399 | DateUtil.DatePattern datePattern = DateUtil.DatePattern.ONLY_HOUR_MINUTE;
400 | switch (time) {
401 | case Constants.FIVE_SECOND:
402 | datePattern = DateUtil.DatePattern.ONLY_TIME;
403 | break;
404 | case Constants.ONE_MINUTE:
405 | case Constants.FIVE_MINUTE:
406 | case Constants.FIFTEEN_MINUTE:
407 | case Constants.THIRTY_MINUTE:
408 | datePattern = DateUtil.DatePattern.ONLY_HOUR_MINUTE;
409 | break;
410 | case Constants.SIXTY_MINUTE:
411 | case Constants.ONE_DAY:
412 | case Constants.ONE_WEEK:
413 | datePattern = DateUtil.DatePattern.ONLY_MONTH_SEC;
414 | break;
415 | case Constants.ONE_MON:
416 | datePattern = DateUtil.DatePattern.ONLY_DAY;
417 | break;
418 | }
419 |
420 | return datePattern;
421 | }
422 |
423 | public static Long getT(String time) {
424 | long t = 0;
425 | switch (time) {
426 | case Constants.FIVE_SECOND:
427 | t = 1000 * 5;
428 | break;
429 | case Constants.ONE_MINUTE:
430 | t = 1000 * 60;
431 | break;
432 | case Constants.FIVE_MINUTE:
433 | t = 1000 * 60 * 5;
434 | break;
435 | case Constants.FIFTEEN_MINUTE:
436 | t = 1000 * 60 * 15;
437 | break;
438 | case Constants.THIRTY_MINUTE:
439 | t = 1000 * 60 * 30;
440 | break;
441 | case Constants.SIXTY_MINUTE:
442 | t = 1000 * 60 * 60;
443 | break;
444 | case Constants.ONE_DAY:
445 | t = 1000 * 60 * 60 * 24;
446 | break;
447 | case Constants.ONE_WEEK:
448 | t = 1000 * 60 * 60 * 24 * 7;
449 | break;
450 | case Constants.ONE_MON:
451 | t = 1000 * 60 * 60 * 24 * 30;
452 | break;
453 | }
454 |
455 | return t;
456 | }
457 |
458 | private static void calculateVolumeMA(List entries) {
459 | float volumeMa5 = 0;
460 | float volumeMa10 = 0;
461 |
462 | for (int i = 0; i < entries.size(); i++) {
463 | KLineEntity entry = entries.get(i);
464 | volumeMa5 += entry.getVolume();
465 | volumeMa10 += entry.getVolume();
466 |
467 | if (i == 4) {
468 | entry.MA5Volume = (volumeMa5 / 5f);
469 | } else if (i > 4) {
470 | volumeMa5 -= entries.get(i - 5).getVolume();
471 | entry.MA5Volume = volumeMa5 / 5f;
472 | } else {
473 | entry.MA5Volume = 0f;
474 | }
475 |
476 | if (i == 9) {
477 | entry.MA10Volume = volumeMa10 / 10f;
478 | } else if (i > 9) {
479 | volumeMa10 -= entries.get(i - 10).getVolume();
480 | entry.MA10Volume = volumeMa10 / 10f;
481 | } else {
482 | entry.MA10Volume = 0f;
483 | }
484 | }
485 | }
486 | }
487 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/KLineChartAdapter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import static com.github.fujianlian.klinechart.utils.Constants.RANG_ITEM;
7 |
8 | /**
9 | * 数据适配器
10 | * Created by tifezh on 2016/6/18.
11 | */
12 | public class KLineChartAdapter extends BaseKLineChartAdapter {
13 |
14 | private List datas = new ArrayList<>();
15 | // private List dates = new ArrayList<>();
16 |
17 |
18 | public KLineChartAdapter() {
19 |
20 | }
21 |
22 | @Override
23 | public int getCount() {
24 | return datas.size();
25 | }
26 |
27 | @Override
28 | public Object getItem(int position) {
29 | if (position < datas.size())
30 | return datas.get(position);
31 | else return datas.get(datas.size() - 1);
32 | }
33 |
34 |
35 | public List getDatas() {
36 | return datas;
37 | }
38 |
39 | @Override
40 | public String getDate(int position) {
41 | if (position < datas.size())
42 | return datas.get(position).Date;
43 | else return datas.get(datas.size() - 1).Date;
44 |
45 |
46 | }
47 |
48 | @Override
49 | public String getTimeStamp(int position) {
50 | if (position < datas.size())
51 | return datas.get(position).timestamp;
52 | else return datas.get(datas.size() - 1).timestamp;
53 | }
54 |
55 |
56 | /**
57 | * 向头部添加数据
58 | */
59 | public void addHeaderData(List data) {
60 | if (data != null && !data.isEmpty()) {
61 | datas.clear();
62 | datas.addAll(data);
63 | }
64 | }
65 |
66 | /**
67 | * 向尾部添加数据
68 | */
69 | public void addFooterData(List data) {
70 | if (data != null && !data.isEmpty()) {
71 | datas.clear();
72 | datas.addAll(data);
73 | }
74 | }
75 |
76 |
77 | // public void addDates(List dates) {
78 | // if (dates != null && !dates.isEmpty()) {
79 | // this.dates.clear();
80 | // this.dates.addAll(dates);
81 | // }
82 | // }
83 |
84 | public void addData(KLineEntity entity, int choosePosition, String type) {
85 | if (datas.size() < RANG_ITEM)
86 | return;
87 | datas.add(datas.size() - RANG_ITEM, entity);
88 | // DataHelper.calculateEndData(datas, choosePosition, type, entity.getOpenPrice());
89 | DataHelper.calculate(datas);
90 |
91 | }
92 |
93 | public void replaceData(KLineEntity entity, int choosePosition, String type) {
94 | if (datas.size() > 0) {
95 | datas.set(datas.size() - RANG_ITEM-1, entity);
96 | }
97 | // DataHelper.calculateEndData(datas, choosePosition, type, entity.getOpenPrice());
98 | DataHelper.calculate(datas);
99 | }
100 |
101 |
102 | public KLineEntity getData() {
103 |
104 | if (datas.size() > 0)
105 | return datas.get(0);
106 | else return new KLineEntity();
107 | }
108 |
109 | /**
110 | * 改变某个点的值
111 | *
112 | * @param position 索引值
113 | */
114 | public void changeItem(int position, KLineEntity data) {
115 | datas.set(position, data);
116 | notifyDataSetChanged();
117 | }
118 |
119 | /**
120 | * 数据清除
121 | */
122 | public void clearData() {
123 | datas.clear();
124 | notifyDataSetChanged();
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/KLineChartView.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Color;
6 | import android.support.annotation.ColorRes;
7 | import android.support.annotation.DimenRes;
8 | import android.support.v4.content.ContextCompat;
9 | import android.util.AttributeSet;
10 | import android.view.MotionEvent;
11 | import android.view.View;
12 | import android.widget.ProgressBar;
13 |
14 | import com.github.fujianlian.klinechart.draw.KDJDraw;
15 | import com.github.fujianlian.klinechart.draw.MACDDraw;
16 | import com.github.fujianlian.klinechart.draw.MainDraw;
17 | import com.github.fujianlian.klinechart.draw.RSIDraw;
18 | import com.github.fujianlian.klinechart.draw.VolumeDraw;
19 | import com.github.fujianlian.klinechart.draw.WRDraw;
20 |
21 | /**
22 | * k线图
23 | * Created by tian on 2016/5/20.
24 | */
25 | public class KLineChartView extends BaseKLineChartView {
26 |
27 | ProgressBar mProgressBar;
28 | private boolean isRefreshing = false;
29 | private boolean isLoadMoreEnd = false;
30 | private boolean mLastScrollEnable;
31 | private boolean mLastScaleEnable;
32 |
33 | private KChartRefreshListener mRefreshListener;
34 |
35 | private MACDDraw mMACDDraw;
36 | private RSIDraw mRSIDraw;
37 | private MainDraw mMainDraw;
38 | private KDJDraw mKDJDraw;
39 | private WRDraw mWRDraw;
40 | private VolumeDraw mVolumeDraw;
41 |
42 |
43 | public KLineChartView(Context context) {
44 | this(context, null);
45 | }
46 |
47 | public KLineChartView(Context context, AttributeSet attrs) {
48 | this(context, attrs, 0);
49 | }
50 |
51 | public KLineChartView(Context context, AttributeSet attrs, int defStyleAttr) {
52 | super(context, attrs, defStyleAttr);
53 | initView();
54 | initAttrs(attrs);
55 | }
56 |
57 | private void initView() {
58 | mProgressBar = new ProgressBar(getContext());
59 | LayoutParams layoutParams = new LayoutParams(dp2px(50), dp2px(50));
60 | layoutParams.addRule(CENTER_IN_PARENT);
61 | addView(mProgressBar, layoutParams);
62 | mProgressBar.setVisibility(GONE);
63 | mVolumeDraw = new VolumeDraw(this);
64 | mMACDDraw = new MACDDraw(this);
65 | mWRDraw = new WRDraw(this);
66 | mKDJDraw = new KDJDraw(this);
67 | mRSIDraw = new RSIDraw(this);
68 | mMainDraw = new MainDraw(this);
69 | addChildDraw(mMACDDraw);
70 | addChildDraw(mKDJDraw);
71 | addChildDraw(mRSIDraw);
72 | // addChildDraw(mVolumeDraw);
73 | // addChildDraw(mRSIDraw);
74 | addVolDraw(mVolumeDraw);
75 | // addChildDraw(mKDJDraw);
76 | // setVolDraw(mVolumeDraw);
77 | // addChildDraw(mVolumeDraw);
78 | setMainDraw(mMainDraw);
79 | }
80 |
81 | private void initAttrs(AttributeSet attrs) {
82 | TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.KLineChartView);
83 | if (array != null) {
84 | try {
85 | //public
86 | setPointWidth(array.getDimension(R.styleable.KLineChartView_kc_point_width, getDimension(R.dimen.chart_point_width)));
87 | setTextSize(array.getDimension(R.styleable.KLineChartView_kc_text_size, getDimension(R.dimen.chart_text_size)));
88 | setTextColor(array.getColor(R.styleable.KLineChartView_kc_text_color, getColor(R.color.chart_white)));
89 | setMTextSize(array.getDimension(R.styleable.KLineChartView_kc_text_size, getDimension(R.dimen.chart_text_size)));
90 | setMTextColor(array.getColor(R.styleable.KLineChartView_kc_text_color, getColor(R.color.chart_white)));
91 | setLineWidth(array.getDimension(R.styleable.KLineChartView_kc_line_width, getDimension(R.dimen.chart_line_width)));
92 | setBackgroundColor(array.getColor(R.styleable.KLineChartView_kc_background_color, getColor(R.color.chart_bac)));
93 | setSelectPointColor(array.getColor(R.styleable.KLineChartView_kc_background_color, getColor(R.color.chart_point_bac)));
94 |
95 | setSelectedXLineColor(getColor(R.color.chart_line_color));
96 | setSelectedXLineWidth(getDimension(R.dimen.chart_line_width));
97 |
98 | setSelectedYLineColor(Color.parseColor("#8040424D"));
99 | setSelectedYLineWidth(getDimension(R.dimen.chart_point_width));
100 |
101 | setGridLineWidth(array.getDimension(R.styleable.KLineChartView_kc_grid_line_width, getDimension(R.dimen.chart_grid_line_width)));
102 | setGridLineColor(array.getColor(R.styleable.KLineChartView_kc_grid_line_color, getColor(R.color.chart_grid_line)));
103 | // setGridLineColor(getColor(R.color.chart_ma5));
104 | //macd
105 | setMACDWidth(array.getDimension(R.styleable.KLineChartView_kc_macd_width, getDimension(R.dimen.chart_candle_width)));
106 | setDIFColor(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
107 | setDEAColor(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
108 | setMACDColor(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
109 | //kdj
110 | setKColor(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
111 | setDColor(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
112 | setJColor(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
113 | //wr
114 | setRColor(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
115 | //rsi
116 | setRSI1Color(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
117 | setRSI2Color(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
118 | setRSI3Color(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
119 | //main
120 | setMa5Color(array.getColor(R.styleable.KLineChartView_kc_dif_color, getColor(R.color.chart_ma5)));
121 | setMa10Color(array.getColor(R.styleable.KLineChartView_kc_dea_color, getColor(R.color.chart_ma10)));
122 | setMa30Color(array.getColor(R.styleable.KLineChartView_kc_macd_color, getColor(R.color.chart_ma30)));
123 | setCandleWidth(array.getDimension(R.styleable.KLineChartView_kc_candle_width, getDimension(R.dimen.chart_candle_width)));
124 | setCandleLineWidth(array.getDimension(R.styleable.KLineChartView_kc_candle_line_width, getDimension(R.dimen.chart_candle_line_width)));
125 | setSelectorBackgroundColor(array.getColor(R.styleable.KLineChartView_kc_selector_background_color, getColor(R.color.chart_selector_new)));
126 | setSelectorTextSize(array.getDimension(R.styleable.KLineChartView_kc_selector_text_size, getDimension(R.dimen.chart_selector_text_size)));
127 | setCandleSolid(array.getBoolean(R.styleable.KLineChartView_kc_candle_solid, true));
128 | } catch (Exception e) {
129 | e.printStackTrace();
130 | } finally {
131 | array.recycle();
132 | }
133 | }
134 | }
135 |
136 | private float getDimension(@DimenRes int resId) {
137 | return getResources().getDimension(resId);
138 | }
139 |
140 | private int getColor(@ColorRes int resId) {
141 | return ContextCompat.getColor(getContext(), resId);
142 | }
143 |
144 | @Override
145 | public void onLeftSide() {
146 | // showLoading();
147 | }
148 |
149 | @Override
150 | public void onRightSide() {
151 |
152 | }
153 |
154 | public void showLoading() {
155 | if (!isLoadMoreEnd && !isRefreshing) {
156 | isRefreshing = true;
157 | if (mProgressBar != null) {
158 | mProgressBar.setVisibility(View.VISIBLE);
159 | }
160 | if (mRefreshListener != null) {
161 | mRefreshListener.onLoadMoreBegin(this);
162 | }
163 | mLastScaleEnable = isScaleEnable();
164 | mLastScrollEnable = isScrollEnable();
165 | super.setScrollEnable(false);
166 | super.setScaleEnable(false);
167 | }
168 | }
169 |
170 | public void justShowLoading() {
171 | if (!isRefreshing) {
172 | isLongPress = false;
173 | isRefreshing = true;
174 | if (mProgressBar != null) {
175 | mProgressBar.setVisibility(View.VISIBLE);
176 | }
177 | if (mRefreshListener != null) {
178 | mRefreshListener.onLoadMoreBegin(this);
179 | }
180 | mLastScaleEnable = isScaleEnable();
181 | mLastScrollEnable = isScrollEnable();
182 | super.setScrollEnable(false);
183 | super.setScaleEnable(false);
184 | }
185 | }
186 |
187 | private void hideLoading() {
188 | if (mProgressBar != null) {
189 | mProgressBar.setVisibility(View.GONE);
190 | }
191 | super.setScrollEnable(mLastScrollEnable);
192 | super.setScaleEnable(mLastScaleEnable);
193 | }
194 |
195 | /**
196 | * 隐藏选择器内容
197 | */
198 | public void hideSelectData() {
199 | isLongPress = false;
200 | invalidate();
201 | }
202 |
203 | /**
204 | * 刷新完成
205 | */
206 | public void refreshComplete() {
207 | isRefreshing = false;
208 | hideLoading();
209 | }
210 |
211 | /**
212 | * 刷新完成,没有数据
213 | */
214 | public void refreshEnd() {
215 | isLoadMoreEnd = true;
216 | isRefreshing = false;
217 | hideLoading();
218 | }
219 |
220 | /**
221 | * 重置加载更多
222 | */
223 | public void resetLoadMoreEnd() {
224 | isLoadMoreEnd = false;
225 | }
226 |
227 | public void setLoadMoreEnd() {
228 | isLoadMoreEnd = true;
229 | }
230 |
231 | public interface KChartRefreshListener {
232 | /**
233 | * 加载更多
234 | *
235 | * @param chart
236 | */
237 | void onLoadMoreBegin(KLineChartView chart);
238 | }
239 |
240 | @Override
241 | public void setScaleEnable(boolean scaleEnable) {
242 | if (isRefreshing) {
243 | throw new IllegalStateException("请勿在刷新状态设置属性");
244 | }
245 | super.setScaleEnable(scaleEnable);
246 |
247 | }
248 |
249 | @Override
250 | public void setScrollEnable(boolean scrollEnable) {
251 | if (isRefreshing) {
252 | throw new IllegalStateException("请勿在刷新状态设置属性");
253 | }
254 | super.setScrollEnable(scrollEnable);
255 | }
256 |
257 | /**
258 | * 设置DIF颜色
259 | */
260 | public void setDIFColor(int color) {
261 | mMACDDraw.setDIFColor(color);
262 | }
263 |
264 | /**
265 | * 设置DEA颜色
266 | */
267 | public void setDEAColor(int color) {
268 | mMACDDraw.setDEAColor(color);
269 | }
270 |
271 | /**
272 | * 设置MACD颜色
273 | */
274 | public void setMACDColor(int color) {
275 | mMACDDraw.setMACDColor(color);
276 | }
277 |
278 | /**
279 | * 设置MACD的宽度
280 | *
281 | * @param MACDWidth
282 | */
283 | public void setMACDWidth(float MACDWidth) {
284 | mMACDDraw.setMACDWidth(MACDWidth);
285 | }
286 |
287 | /**
288 | * 设置K颜色
289 | */
290 | public void setKColor(int color) {
291 | mKDJDraw.setKColor(color);
292 | }
293 |
294 | /**
295 | * 设置D颜色
296 | */
297 | public void setDColor(int color) {
298 | mKDJDraw.setDColor(color);
299 | }
300 |
301 | /**
302 | * 设置J颜色
303 | */
304 | public void setJColor(int color) {
305 | mKDJDraw.setJColor(color);
306 | }
307 |
308 | /**
309 | * 设置R颜色
310 | */
311 | public void setRColor(int color) {
312 | mWRDraw.setRColor(color);
313 | }
314 |
315 | /**
316 | * 设置ma5颜色
317 | *
318 | * @param color
319 | */
320 | public void setMa5Color(int color) {
321 | mMainDraw.setMa5Color(color);
322 | mVolumeDraw.setMa5Color(color);
323 | }
324 |
325 | /**
326 | * 设置ma10颜色
327 | *
328 | * @param color
329 | */
330 | public void setMa10Color(int color) {
331 | mMainDraw.setMa10Color(color);
332 | mVolumeDraw.setMa10Color(color);
333 | }
334 |
335 | /**
336 | * 设置ma20颜色
337 | *
338 | * @param color
339 | */
340 | public void setMa30Color(int color) {
341 | mMainDraw.setMa30Color(color);
342 | }
343 |
344 | /**
345 | * 设置选择器文字大小
346 | *
347 | * @param textSize
348 | */
349 | public void setSelectorTextSize(float textSize) {
350 | mMainDraw.setSelectorTextSize(textSize);
351 | }
352 |
353 | /**
354 | * 设置选择器背景
355 | *
356 | * @param color
357 | */
358 | public void setSelectorBackgroundColor(int color) {
359 | mMainDraw.setSelectorBackgroundColor(color);
360 | }
361 |
362 | /**
363 | * 设置蜡烛宽度
364 | *
365 | * @param candleWidth
366 | */
367 | public void setCandleWidth(float candleWidth) {
368 | mMainDraw.setCandleWidth(candleWidth);
369 | }
370 |
371 | /**
372 | * 设置蜡烛线宽度
373 | *
374 | * @param candleLineWidth
375 | */
376 | public void setCandleLineWidth(float candleLineWidth) {
377 | mMainDraw.setCandleLineWidth(candleLineWidth);
378 | }
379 |
380 | /**
381 | * 蜡烛是否空心
382 | */
383 | public void setCandleSolid(boolean candleSolid) {
384 | mMainDraw.setCandleSolid(candleSolid);
385 | }
386 |
387 | public void setRSI1Color(int color) {
388 | mRSIDraw.setRSI1Color(color);
389 | }
390 |
391 | public void setRSI2Color(int color) {
392 | mRSIDraw.setRSI2Color(color);
393 | }
394 |
395 | public void setRSI3Color(int color) {
396 | mRSIDraw.setRSI3Color(color);
397 | }
398 |
399 | @Override
400 | public void setTextSize(float textSize) {
401 | super.setTextSize(textSize);
402 | mMainDraw.setTextSize(textSize);
403 | mRSIDraw.setTextSize(textSize);
404 | mMACDDraw.setTextSize(textSize);
405 | mKDJDraw.setTextSize(textSize);
406 | mWRDraw.setTextSize(textSize);
407 | mVolumeDraw.setTextSize(textSize);
408 | }
409 |
410 | @Override
411 | public void setLineWidth(float lineWidth) {
412 | super.setLineWidth(lineWidth);
413 | mMainDraw.setLineWidth(lineWidth);
414 | mRSIDraw.setLineWidth(lineWidth);
415 | mMACDDraw.setLineWidth(lineWidth);
416 | mKDJDraw.setLineWidth(lineWidth);
417 | mWRDraw.setLineWidth(lineWidth);
418 | mVolumeDraw.setLineWidth(lineWidth);
419 | }
420 |
421 | @Override
422 | public void setTextColor(int color) {
423 | super.setTextColor(color);
424 | mMainDraw.setSelectorTextColor(color);
425 | }
426 |
427 | /**
428 | * 设置刷新监听
429 | */
430 | public void setRefreshListener(KChartRefreshListener refreshListener) {
431 | mRefreshListener = refreshListener;
432 | }
433 |
434 | public void setMainDrawLine(boolean isLine) {
435 | mMainDraw.setLine(isLine);
436 | invalidate();
437 | }
438 |
439 | public void setMainRangLine(boolean isLine) {
440 | mMainDraw.setRange(isLine);
441 | invalidate();
442 | }
443 |
444 | public void setKlineType(String klineType) {
445 | mMainDraw.setKlineType(klineType);
446 | invalidate();
447 | }
448 |
449 |
450 | private int startX;
451 | private int startY;
452 |
453 | @Override
454 | public boolean onInterceptTouchEvent(MotionEvent ev) {
455 | switch (ev.getAction()) {
456 | case MotionEvent.ACTION_DOWN:
457 | startX = (int) ev.getX();
458 | startY = (int) ev.getY();
459 | break;
460 | case MotionEvent.ACTION_MOVE:
461 | int dX = (int) (ev.getX() - startX);
462 | int dY = (int) (ev.getY() - startX);
463 | if (Math.abs(dX) > Math.abs(dY)) {
464 | //左右滑动
465 | return true;
466 | } else {
467 | //上下滑动
468 | return false;
469 | }
470 | case MotionEvent.ACTION_UP:
471 | break;
472 | default:
473 | }
474 | return super.onInterceptTouchEvent(ev);
475 | }
476 |
477 | @Override
478 | public void onLongPress(MotionEvent e) {
479 | if (!isRefreshing) {
480 | super.onLongPress(e);
481 | }
482 | }
483 | }
484 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/KLineEntity.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import com.github.fujianlian.klinechart.entity.IKLine;
7 |
8 | import java.io.Serializable;
9 |
10 | /**
11 | * K线实体
12 | * Created by tifezh on 2016/5/16.
13 | */
14 | public class KLineEntity implements IKLine, Parcelable {
15 |
16 | public String address;
17 |
18 | public String getAddress() {
19 | return address;
20 | }
21 |
22 | public void setAddress(String address) {
23 | this.address = address;
24 | }
25 |
26 | public String getDate() {
27 | return Date;
28 | }
29 |
30 | @Override
31 | public float getOpenPrice() {
32 | return Open;
33 | }
34 |
35 | @Override
36 | public float getHighPrice() {
37 | return High;
38 | }
39 |
40 | @Override
41 | public float getLowPrice() {
42 | return Low;
43 | }
44 |
45 | @Override
46 | public float getClosePrice() {
47 | return Close;
48 | }
49 |
50 | @Override
51 | public float getMA5Price() {
52 | return MA5Price;
53 | }
54 |
55 | @Override
56 | public float getMA10Price() {
57 | return MA10Price;
58 | }
59 |
60 | @Override
61 | public float getMA20Price() {
62 | return MA20Price;
63 | }
64 |
65 | @Override
66 | public float getMA30Price() {
67 | return MA30Price;
68 | }
69 |
70 | @Override
71 | public float getMA60Price() {
72 | return MA60Price;
73 | }
74 |
75 | @Override
76 | public float getDea() {
77 | return dea;
78 | }
79 |
80 | @Override
81 | public float getDif() {
82 | return dif;
83 | }
84 |
85 | @Override
86 | public float getMacd() {
87 | return macd;
88 | }
89 |
90 | @Override
91 | public float getK() {
92 | return k;
93 | }
94 |
95 | @Override
96 | public float getD() {
97 | return d;
98 | }
99 |
100 | @Override
101 | public float getJ() {
102 | return j;
103 | }
104 |
105 | @Override
106 | public float getR() {
107 | return r;
108 | }
109 |
110 | @Override
111 | public float getRsi() {
112 | return rsi;
113 | }
114 |
115 | @Override
116 | public float getUp() {
117 | return up;
118 | }
119 |
120 | @Override
121 | public float getMb() {
122 | return mb;
123 | }
124 |
125 | @Override
126 | public float getDn() {
127 | return dn;
128 | }
129 |
130 | @Override
131 | public float getVolume() {
132 | return Volume;
133 | }
134 |
135 | @Override
136 | public float getMA5Volume() {
137 | return MA5Volume;
138 | }
139 |
140 | @Override
141 | public float getMA10Volume() {
142 | return MA10Volume;
143 | }
144 |
145 | public int type;
146 |
147 |
148 | public int getType() {
149 | return type;
150 | }
151 |
152 | public void setType(int type) {
153 | this.type = type;
154 | }
155 |
156 | public String Date;
157 | public String timestamp;
158 | public String t;
159 | public float Open;
160 | public float High;
161 | public float Low;
162 | public float Close;
163 | public float Volume;
164 |
165 | public float MA5Price;
166 |
167 | public float MA10Price;
168 |
169 | public float MA20Price;
170 |
171 | public float MA30Price;
172 |
173 | public float MA60Price;
174 |
175 | public float dea;
176 |
177 | public float dif;
178 |
179 | public float macd;
180 |
181 | public float k;
182 |
183 | public float d;
184 |
185 | public float j;
186 |
187 | public float r;
188 |
189 | public float rsi;
190 |
191 | public float up;
192 |
193 | public float mb;
194 |
195 | public float dn;
196 |
197 | public float MA5Volume;
198 |
199 | public float MA10Volume;
200 |
201 | public void setDate(String date) {
202 | Date = date;
203 | }
204 |
205 | public void setTimestamp(String timestamp) {
206 | this.timestamp = timestamp;
207 | }
208 |
209 | public String getTimestamp() {
210 | return timestamp;
211 | }
212 |
213 | public String getT() {
214 | return t;
215 | }
216 |
217 | public void setT(String t) {
218 | this.t = t;
219 | }
220 |
221 | public void setOpen(float open) {
222 | Open = open;
223 | }
224 |
225 | public void setHigh(float high) {
226 | High = high;
227 | }
228 |
229 | public void setLow(float low) {
230 | Low = low;
231 | }
232 |
233 | public void setClose(float close) {
234 | Close = close;
235 | }
236 |
237 | public void setVolume(float volume) {
238 | Volume = volume;
239 | }
240 |
241 | public void setMA5Price(float MA5Price) {
242 | this.MA5Price = MA5Price;
243 | }
244 |
245 | public void setMA10Price(float MA10Price) {
246 | this.MA10Price = MA10Price;
247 | }
248 |
249 | public void setMA20Price(float MA20Price) {
250 | this.MA20Price = MA20Price;
251 | }
252 |
253 | public void setMA30Price(float MA30Price) {
254 | this.MA30Price = MA30Price;
255 | }
256 |
257 | public void setMA60Price(float MA60Price) {
258 | this.MA60Price = MA60Price;
259 | }
260 |
261 | public void setDea(float dea) {
262 | this.dea = dea;
263 | }
264 |
265 | public void setDif(float dif) {
266 | this.dif = dif;
267 | }
268 |
269 | public void setMacd(float macd) {
270 | this.macd = macd;
271 | }
272 |
273 | public void setK(float k) {
274 | this.k = k;
275 | }
276 |
277 | public void setD(float d) {
278 | this.d = d;
279 | }
280 |
281 | public void setJ(float j) {
282 | this.j = j;
283 | }
284 |
285 | public void setR(float r) {
286 | this.r = r;
287 | }
288 |
289 | public void setRsi(float rsi) {
290 | this.rsi = rsi;
291 | }
292 |
293 | public void setUp(float up) {
294 | this.up = up;
295 | }
296 |
297 | public void setMb(float mb) {
298 | this.mb = mb;
299 | }
300 |
301 | public void setDn(float dn) {
302 | this.dn = dn;
303 | }
304 |
305 | public void setMA5Volume(float MA5Volume) {
306 | this.MA5Volume = MA5Volume;
307 | }
308 |
309 | public void setMA10Volume(float MA10Volume) {
310 | this.MA10Volume = MA10Volume;
311 | }
312 |
313 | @Override
314 | public int describeContents() {
315 | return 0;
316 | }
317 |
318 | @Override
319 | public void writeToParcel(Parcel dest, int flags) {
320 | dest.writeString(this.address);
321 | dest.writeInt(this.type);
322 | dest.writeString(this.Date);
323 | dest.writeFloat(this.Open);
324 | dest.writeFloat(this.High);
325 | dest.writeFloat(this.Low);
326 | dest.writeFloat(this.Close);
327 | dest.writeFloat(this.Volume);
328 | dest.writeFloat(this.MA5Price);
329 | dest.writeFloat(this.MA10Price);
330 | dest.writeFloat(this.MA20Price);
331 | dest.writeFloat(this.MA30Price);
332 | dest.writeFloat(this.MA60Price);
333 | dest.writeFloat(this.dea);
334 | dest.writeFloat(this.dif);
335 | dest.writeFloat(this.macd);
336 | dest.writeFloat(this.k);
337 | dest.writeFloat(this.d);
338 | dest.writeFloat(this.j);
339 | dest.writeFloat(this.r);
340 | dest.writeFloat(this.rsi);
341 | dest.writeFloat(this.up);
342 | dest.writeFloat(this.mb);
343 | dest.writeFloat(this.dn);
344 | dest.writeFloat(this.MA5Volume);
345 | dest.writeFloat(this.MA10Volume);
346 | }
347 |
348 | public KLineEntity() {
349 | }
350 |
351 | protected KLineEntity(Parcel in) {
352 | this.address = in.readString();
353 | this.type = in.readInt();
354 | this.Date = in.readString();
355 | this.Open = in.readFloat();
356 | this.High = in.readFloat();
357 | this.Low = in.readFloat();
358 | this.Close = in.readFloat();
359 | this.Volume = in.readFloat();
360 | this.MA5Price = in.readFloat();
361 | this.MA10Price = in.readFloat();
362 | this.MA20Price = in.readFloat();
363 | this.MA30Price = in.readFloat();
364 | this.MA60Price = in.readFloat();
365 | this.dea = in.readFloat();
366 | this.dif = in.readFloat();
367 | this.macd = in.readFloat();
368 | this.k = in.readFloat();
369 | this.d = in.readFloat();
370 | this.j = in.readFloat();
371 | this.r = in.readFloat();
372 | this.rsi = in.readFloat();
373 | this.up = in.readFloat();
374 | this.mb = in.readFloat();
375 | this.dn = in.readFloat();
376 | this.MA5Volume = in.readFloat();
377 | this.MA10Volume = in.readFloat();
378 | }
379 |
380 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
381 | @Override
382 | public KLineEntity createFromParcel(Parcel source) {
383 | return new KLineEntity(source);
384 | }
385 |
386 | @Override
387 | public KLineEntity[] newArray(int size) {
388 | return new KLineEntity[size];
389 | }
390 | };
391 | }
392 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/ScrollAndScaleView.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.GestureDetectorCompat;
5 | import android.util.AttributeSet;
6 | import android.util.Log;
7 | import android.view.GestureDetector;
8 | import android.view.MotionEvent;
9 | import android.view.ScaleGestureDetector;
10 | import android.widget.OverScroller;
11 | import android.widget.RelativeLayout;
12 |
13 | /**
14 | * 可以滑动和放大的view
15 | * Created by tian on 2016/5/3.
16 | */
17 | public abstract class ScrollAndScaleView extends RelativeLayout implements
18 | GestureDetector.OnGestureListener,
19 | ScaleGestureDetector.OnScaleGestureListener {
20 | protected int mScrollX = 0;
21 | protected GestureDetectorCompat mDetector;
22 | protected ScaleGestureDetector mScaleDetector;
23 |
24 | protected boolean isLongPress = false;
25 |
26 | private OverScroller mScroller;
27 |
28 | protected boolean touch = false;
29 |
30 | protected float mScaleX = 1;
31 |
32 | protected float mScaleXMax = 4f;
33 |
34 | protected float mScaleXMin = 0.5f;
35 |
36 | private boolean mMultipleTouch = false;
37 |
38 | private boolean mScrollEnable = true;
39 |
40 | private boolean mScaleEnable = true;
41 |
42 | public ScrollAndScaleView(Context context) {
43 | super(context);
44 | init();
45 | }
46 |
47 | public ScrollAndScaleView(Context context, AttributeSet attrs) {
48 | super(context, attrs);
49 | init();
50 | }
51 |
52 | public ScrollAndScaleView(Context context, AttributeSet attrs, int defStyleAttr) {
53 | super(context, attrs, defStyleAttr);
54 | init();
55 | }
56 |
57 | private void init() {
58 | setWillNotDraw(false);
59 | mDetector = new GestureDetectorCompat(getContext(), this);
60 | mScaleDetector = new ScaleGestureDetector(getContext(), this);
61 | mScroller = new OverScroller(getContext());
62 | }
63 |
64 | @Override
65 | public boolean onDown(MotionEvent e) {
66 | return false;
67 | }
68 |
69 | @Override
70 | public void onShowPress(MotionEvent e) {
71 |
72 | }
73 |
74 | @Override
75 | public boolean onSingleTapUp(MotionEvent e) {
76 | return false;
77 | }
78 |
79 | @Override
80 | public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
81 | if (!isLongPress && !isMultipleTouch()) {
82 | scrollBy(Math.round(distanceX), 0);
83 | return true;
84 | }
85 | return false;
86 | }
87 |
88 | @Override
89 | public void onLongPress(MotionEvent e) {
90 | isLongPress = true;
91 | }
92 |
93 | @Override
94 | public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
95 | if (!isTouch() && isScrollEnable()) {
96 | mScroller.fling(mScrollX, 0
97 | , Math.round(velocityX / mScaleX), 0,
98 | Integer.MIN_VALUE, Integer.MAX_VALUE,
99 | 0, 0);
100 | }
101 | return true;
102 | }
103 |
104 | @Override
105 | public void computeScroll() {
106 | if (mScroller.computeScrollOffset()) {
107 | if (!isTouch()) {
108 | scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
109 | } else {
110 | mScroller.forceFinished(true);
111 | }
112 | }
113 | }
114 |
115 | @Override
116 | public void scrollBy(int x, int y) {
117 | scrollTo(mScrollX - Math.round(x / mScaleX), 0);
118 | }
119 |
120 | @Override
121 | public void scrollTo(int x, int y) {
122 | Log.i("x---", x + "");
123 | if (!isScrollEnable()) {
124 | mScroller.forceFinished(true);
125 | return;
126 | }
127 | int oldX = mScrollX;
128 | mScrollX = x;
129 | if (mScrollX < getMinScrollX()) {
130 | mScrollX = getMinScrollX();
131 | onRightSide();
132 | mScroller.forceFinished(true);
133 | } else if (mScrollX > getMaxScrollX()) {
134 | mScrollX = getMaxScrollX();
135 | onLeftSide();
136 | mScroller.forceFinished(true);
137 | }
138 | Log.i("mScrollX---", mScrollX + "");
139 | onScrollChanged(mScrollX, 0, oldX, 0);
140 | invalidate();
141 | }
142 |
143 | @Override
144 | public boolean onScale(ScaleGestureDetector detector) {
145 | if (!isScaleEnable()) {
146 | return false;
147 | }
148 | float oldScale = mScaleX;
149 | mScaleX *= detector.getScaleFactor();
150 | if (mScaleX < mScaleXMin) {
151 | mScaleX = mScaleXMin;
152 | } else if (mScaleX > mScaleXMax) {
153 | mScaleX = mScaleXMax;
154 | } else {
155 | onScaleChanged(mScaleX, oldScale);
156 | }
157 | return true;
158 | }
159 |
160 | protected void onScaleChanged(float scale, float oldScale) {
161 | invalidate();
162 | }
163 |
164 | @Override
165 | public boolean onScaleBegin(ScaleGestureDetector detector) {
166 | return true;
167 | }
168 |
169 | @Override
170 | public void onScaleEnd(ScaleGestureDetector detector) {
171 |
172 | }
173 |
174 | float x;
175 |
176 | @Override
177 | public boolean onTouchEvent(MotionEvent event) {
178 | // 按压手指超过1个
179 | if (event.getPointerCount() > 1) {
180 | isLongPress = false;
181 | }
182 | switch (event.getAction() & MotionEvent.ACTION_MASK) {
183 | case MotionEvent.ACTION_DOWN:
184 | touch = true;
185 | x = event.getX();
186 | break;
187 | case MotionEvent.ACTION_MOVE:
188 | //长按之后移动
189 | if (isLongPress) {
190 | onLongPress(event);
191 | }
192 | break;
193 | case MotionEvent.ACTION_POINTER_UP:
194 | invalidate();
195 | break;
196 | case MotionEvent.ACTION_UP:
197 | // if (x == event.getX()) {
198 | // if (isLongPress) {
199 | // isLongPress = false;
200 | // }
201 | // }
202 | if (isLongPress) {
203 | isLongPress = false;
204 | }
205 | touch = false;
206 | invalidate();
207 | break;
208 | case MotionEvent.ACTION_CANCEL:
209 | isLongPress = false;
210 | touch = false;
211 | invalidate();
212 | break;
213 | default:
214 | break;
215 | }
216 | mMultipleTouch = event.getPointerCount() > 1;
217 | this.mDetector.onTouchEvent(event);
218 | this.mScaleDetector.onTouchEvent(event);
219 | return true;
220 | }
221 |
222 |
223 | /**
224 | * 滑到了最左边
225 | */
226 | abstract public void onLeftSide();
227 |
228 | /**
229 | * 滑到了最右边
230 | */
231 | abstract public void onRightSide();
232 |
233 | /**
234 | * 是否在触摸中
235 | *
236 | * @return
237 | */
238 | public boolean isTouch() {
239 | return touch;
240 | }
241 |
242 | /**
243 | * 获取位移的最小值
244 | *
245 | * @return
246 | */
247 | public abstract int getMinScrollX();
248 |
249 | /**
250 | * 获取位移的最大值
251 | *
252 | * @return
253 | */
254 | public abstract int getMaxScrollX();
255 |
256 | /**
257 | * 设置ScrollX
258 | *
259 | * @param scrollX
260 | */
261 | public void setScrollX(int scrollX) {
262 | this.mScrollX = scrollX;
263 | scrollTo(scrollX, 0);
264 | }
265 |
266 | /**
267 | * 是否是多指触控
268 | *
269 | * @return
270 | */
271 | public boolean isMultipleTouch() {
272 | return mMultipleTouch;
273 | }
274 |
275 | protected void checkAndFixScrollX() {
276 | if (mScrollX < getMinScrollX()) {
277 | mScrollX = getMinScrollX();
278 | mScroller.forceFinished(true);
279 | } else if (mScrollX > getMaxScrollX()) {
280 | mScrollX = getMaxScrollX();
281 | mScroller.forceFinished(true);
282 | }
283 | }
284 |
285 | public float getScaleXMax() {
286 | return mScaleXMax;
287 | }
288 |
289 | public float getScaleXMin() {
290 | return mScaleXMin;
291 | }
292 |
293 | public boolean isScrollEnable() {
294 | return mScrollEnable;
295 | }
296 |
297 | public boolean isScaleEnable() {
298 | return mScaleEnable;
299 | }
300 |
301 | /**
302 | * 设置缩放的最大值
303 | */
304 | public void setScaleXMax(float scaleXMax) {
305 | mScaleXMax = scaleXMax;
306 | }
307 |
308 | /**
309 | * 设置缩放的最小值
310 | */
311 | public void setScaleXMin(float scaleXMin) {
312 | mScaleXMin = scaleXMin;
313 | }
314 |
315 | /**
316 | * 设置是否可以滑动
317 | */
318 | public void setScrollEnable(boolean scrollEnable) {
319 | mScrollEnable = scrollEnable;
320 | }
321 |
322 | /**
323 | * 设置是否可以缩放
324 | */
325 | public void setScaleEnable(boolean scaleEnable) {
326 | mScaleEnable = scaleEnable;
327 | }
328 |
329 | @Override
330 | public float getScaleX() {
331 | return mScaleX;
332 | }
333 | }
334 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/base/IAdapter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.base;
2 |
3 | import android.database.DataSetObserver;
4 |
5 | import com.github.fujianlian.klinechart.KLineEntity;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * 数据适配器
11 | * Created by tifezh on 2016/6/14.
12 | */
13 |
14 | public interface IAdapter {
15 | /**
16 | * 获取点的数目
17 | *
18 | * @return
19 | */
20 | int getCount();
21 |
22 | /**
23 | * 通过序号获取item
24 | *
25 | * @param position 对应的序号
26 | * @return 数据实体
27 | */
28 | Object getItem(int position);
29 |
30 |
31 | /**
32 | * 通过序号获取时间
33 | *
34 | * @param position
35 | * @return
36 | */
37 | String getDate(int position);
38 |
39 | String getTimeStamp(int position);
40 |
41 |
42 | /**
43 | * 注册一个数据观察者
44 | *
45 | * @param observer 数据观察者
46 | */
47 | void registerDataSetObserver(DataSetObserver observer);
48 |
49 | /**
50 | * 移除一个数据观察者
51 | *
52 | * @param observer 数据观察者
53 | */
54 | void unregisterDataSetObserver(DataSetObserver observer);
55 |
56 | /**
57 | * 当数据发生变化时调用
58 | */
59 | void notifyDataSetChanged();
60 | }
61 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/base/IChartDraw.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.base;
2 |
3 | import android.graphics.Canvas;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 |
7 | import com.github.fujianlian.klinechart.BaseKLineChartView;
8 |
9 |
10 | /**
11 | * 画图的基类 根据实体来画图形
12 | * Created by tifezh on 2016/6/14.
13 | */
14 | public interface IChartDraw {
15 |
16 | /**
17 | * 需要滑动 物体draw方法
18 | *
19 | * @param canvas canvas
20 | * @param view k线图View
21 | * @param position 当前点的位置
22 | * @param lastPoint 上一个点
23 | * @param curPoint 当前点
24 | * @param lastX 上一个点的x坐标
25 | * @param curX 当前点的X坐标
26 | */
27 | void drawTranslated(@Nullable T lastPoint, @NonNull T curPoint, float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position);
28 |
29 | /**
30 | * @param canvas
31 | * @param view
32 | * @param position 该点的位置
33 | * @param x x的起始坐标
34 | * @param y y的起始坐标
35 | */
36 | void drawText(@NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position, float x, float y);
37 |
38 | /**
39 | * 获取当前实体中最大的值
40 | *
41 | * @param point
42 | * @return
43 | */
44 | float getMaxValue(T point);
45 |
46 | /**
47 | * 获取当前实体中最小的值
48 | *
49 | * @param point
50 | * @return
51 | */
52 | float getMinValue(T point);
53 |
54 |
55 |
56 | /**
57 | * 获取value格式化器
58 | */
59 | IValueFormatter getValueFormatter();
60 | }
61 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/base/IDateTimeFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.base;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * 时间格式化接口
7 | * Created by tifezh on 2016/6/21.
8 | */
9 |
10 | public interface IDateTimeFormatter {
11 | String format(Date date);
12 | }
13 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/base/IValueFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.base;
2 |
3 | /**
4 | * Value格式化接口
5 | * Created by tifezh on 2016/6/21.
6 | */
7 |
8 | public interface IValueFormatter {
9 | /**
10 | * 格式化value
11 | *
12 | * @param value 传入的value值
13 | * @return 返回字符串
14 | */
15 | String format(float value,int digit);
16 | }
17 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/draw/KDJDraw.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.draw;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 |
8 | import com.github.fujianlian.klinechart.BaseKLineChartView;
9 | import com.github.fujianlian.klinechart.base.IChartDraw;
10 | import com.github.fujianlian.klinechart.base.IValueFormatter;
11 | import com.github.fujianlian.klinechart.entity.IKDJ;
12 | import com.github.fujianlian.klinechart.formatter.ValueFormatter;
13 |
14 | import static com.github.fujianlian.klinechart.utils.Constants.RANG_ITEM;
15 |
16 | /**
17 | * KDJ实现类
18 | * Created by tifezh on 2016/6/19.
19 | */
20 |
21 | public class KDJDraw implements IChartDraw {
22 |
23 | private Paint mKPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
24 | private Paint mDPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
25 | private Paint mJPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
26 |
27 | public KDJDraw(BaseKLineChartView view) {
28 | }
29 |
30 | @Override
31 | public void drawTranslated(@Nullable IKDJ lastPoint, @NonNull IKDJ curPoint,
32 | float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position) {
33 | if (lastPoint.getK() != 0) {
34 | view.drawChildLine(canvas, mKPaint, lastX, lastPoint.getK(), curX, curPoint.getK());
35 | }
36 | if (lastPoint.getD() != 0) {
37 | view.drawChildLine(canvas, mDPaint, lastX, lastPoint.getD(), curX, curPoint.getD());
38 | }
39 | if (lastPoint.getJ() != 0) {
40 | view.drawChildLine(canvas, mJPaint, lastX, lastPoint.getJ(), curX, curPoint.getJ());
41 | }
42 | }
43 |
44 | @Override
45 | public void drawText(@NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position, float x, float y) {
46 | IKDJ point = (IKDJ) view.getItem(position);
47 | if (point.getK() != 0) {
48 | String text = "KDJ(14,1,3) ";
49 | canvas.drawText(text, x, y, view.getTextPaint());
50 | x += view.getTextPaint().measureText(text);
51 | text = "K:" + view.formatValue(point.getK()) + " ";
52 | canvas.drawText(text, x, y, mKPaint);
53 | x += mKPaint.measureText(text);
54 | if (point.getD() != 0) {
55 | text = "D:" + view.formatValue(point.getD()) + " ";
56 | canvas.drawText(text, x, y, mDPaint);
57 | x += mDPaint.measureText(text);
58 | text = "J:" + view.formatValue(point.getJ()) + " ";
59 | canvas.drawText(text, x, y, mJPaint);
60 | }
61 | }
62 | }
63 |
64 | @Override
65 | public float getMaxValue(IKDJ point) {
66 | return Math.max(point.getK(), Math.max(point.getD(), point.getJ()));
67 | }
68 |
69 | @Override
70 | public float getMinValue(IKDJ point) {
71 | return Math.min(point.getK(), Math.min(point.getD(), point.getJ()));
72 | }
73 |
74 | @Override
75 | public IValueFormatter getValueFormatter() {
76 | return new ValueFormatter();
77 | }
78 |
79 | /**
80 | * 设置K颜色
81 | */
82 | public void setKColor(int color) {
83 | mKPaint.setColor(color);
84 | }
85 |
86 | /**
87 | * 设置D颜色
88 | */
89 | public void setDColor(int color) {
90 | mDPaint.setColor(color);
91 | }
92 |
93 | /**
94 | * 设置J颜色
95 | */
96 | public void setJColor(int color) {
97 | mJPaint.setColor(color);
98 | }
99 |
100 | /**
101 | * 设置曲线宽度
102 | */
103 | public void setLineWidth(float width) {
104 | mKPaint.setStrokeWidth(width);
105 | mDPaint.setStrokeWidth(width);
106 | mJPaint.setStrokeWidth(width);
107 | }
108 |
109 | /**
110 | * 设置文字大小
111 | */
112 | public void setTextSize(float textSize) {
113 | mKPaint.setTextSize(textSize);
114 | mDPaint.setTextSize(textSize);
115 | mJPaint.setTextSize(textSize);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/draw/MACDDraw.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.draw;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.content.ContextCompat;
9 |
10 | import com.github.fujianlian.klinechart.R;
11 | import com.github.fujianlian.klinechart.BaseKLineChartView;
12 | import com.github.fujianlian.klinechart.base.IChartDraw;
13 | import com.github.fujianlian.klinechart.base.IValueFormatter;
14 | import com.github.fujianlian.klinechart.entity.IMACD;
15 | import com.github.fujianlian.klinechart.formatter.ValueFormatter;
16 |
17 | import static com.github.fujianlian.klinechart.utils.Constants.RANG_ITEM;
18 |
19 | /**
20 | * macd实现类
21 | * Created by tifezh on 2016/6/19.
22 | */
23 |
24 | public class MACDDraw implements IChartDraw {
25 |
26 | private Paint mRedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
27 | private Paint mGreenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
28 | private Paint mDIFPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
29 | private Paint mDEAPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
30 | private Paint mMACDPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
31 | /**
32 | * macd 中柱子的宽度
33 | */
34 | private float mMACDWidth = 0;
35 |
36 | public MACDDraw(BaseKLineChartView view) {
37 | Context context = view.getContext();
38 | mRedPaint.setColor(ContextCompat.getColor(context, R.color.chart_red));
39 | mGreenPaint.setColor(ContextCompat.getColor(context, R.color.chart_green));
40 | }
41 |
42 | @Override
43 | public void drawTranslated(@Nullable IMACD lastPoint, @NonNull IMACD curPoint,
44 | float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position) {
45 | drawMACD(canvas, view, curX, curPoint.getMacd());
46 | view.drawChildLine(canvas, mDIFPaint, lastX, lastPoint.getDea(), curX, curPoint.getDea());
47 | view.drawChildLine(canvas, mDEAPaint, lastX, lastPoint.getDif(), curX, curPoint.getDif());
48 | }
49 |
50 | @Override
51 | public void drawText(@NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position,
52 | float x, float y) {
53 | IMACD point = (IMACD) view.getItem(position);
54 | String text = "MACD ";
55 | // String text = "MACD(12,26,9) ";
56 | // canvas.drawText(text, x, y, view.getTextPaint());
57 | // x += view.getTextPaint().measureText(text);
58 | // text = "MACD:" + view.formatValue(point.getMacd()) + " ";
59 | // canvas.drawText(text, x, y, mMACDPaint);
60 | // x += mMACDPaint.measureText(text);
61 | // text = "DIF:" + view.formatValue(point.getDif()) + " ";
62 | // canvas.drawText(text, x, y, mDEAPaint);
63 | // x += mDIFPaint.measureText(text);
64 | // text = "DEA:" + view.formatValue(point.getDea());
65 | canvas.drawText(text, x, y, mDIFPaint);
66 | }
67 |
68 | @Override
69 | public float getMaxValue(IMACD point) {
70 | return Math.max(point.getMacd(), Math.max(point.getDea(), point.getDif()));
71 | }
72 |
73 | @Override
74 | public float getMinValue(IMACD point) {
75 | return Math.min(point.getMacd(), Math.min(point.getDea(), point.getDif()));
76 | }
77 |
78 | @Override
79 | public IValueFormatter getValueFormatter() {
80 | return new ValueFormatter();
81 | }
82 |
83 | /**
84 | * 画macd
85 | *
86 | * @param canvas
87 | * @param x
88 | * @param macd
89 | */
90 | private void drawMACD(Canvas canvas, BaseKLineChartView view, float x, float macd) {
91 | float macdy = view.getChildY(macd);
92 | float r = mMACDWidth / 2;
93 | float zeroy = view.getChildY(0);
94 | if (macd > 0) {
95 | // left top right bottom
96 | canvas.drawRect(x - r, macdy, x + r, zeroy, mRedPaint);
97 | } else {
98 | canvas.drawRect(x - r, zeroy, x + r, macdy, mGreenPaint);
99 | }
100 | }
101 |
102 | /**
103 | * 设置DIF颜色
104 | */
105 | public void setDIFColor(int color) {
106 | this.mDIFPaint.setColor(color);
107 | }
108 |
109 | /**
110 | * 设置DEA颜色
111 | */
112 | public void setDEAColor(int color) {
113 | this.mDEAPaint.setColor(color);
114 | }
115 |
116 | /**
117 | * 设置MACD颜色
118 | */
119 | public void setMACDColor(int color) {
120 | this.mMACDPaint.setColor(color);
121 | }
122 |
123 | /**
124 | * 设置MACD的宽度
125 | *
126 | * @param MACDWidth
127 | */
128 | public void setMACDWidth(float MACDWidth) {
129 | mMACDWidth = MACDWidth;
130 | }
131 |
132 | /**
133 | * 设置曲线宽度
134 | */
135 | public void setLineWidth(float width) {
136 | mDEAPaint.setStrokeWidth(width);
137 | mDIFPaint.setStrokeWidth(width);
138 | mMACDPaint.setStrokeWidth(width);
139 | }
140 |
141 | /**
142 | * 设置文字大小
143 | */
144 | public void setTextSize(float textSize) {
145 | mDEAPaint.setTextSize(textSize);
146 | mDIFPaint.setTextSize(textSize);
147 | mMACDPaint.setTextSize(textSize);
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/draw/RSIDraw.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.draw;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 |
8 | import com.github.fujianlian.klinechart.BaseKLineChartView;
9 | import com.github.fujianlian.klinechart.base.IChartDraw;
10 | import com.github.fujianlian.klinechart.base.IValueFormatter;
11 | import com.github.fujianlian.klinechart.entity.IRSI;
12 | import com.github.fujianlian.klinechart.formatter.ValueFormatter;
13 |
14 | /**
15 | * RSI实现类
16 | * Created by tifezh on 2016/6/19.
17 | */
18 | public class RSIDraw implements IChartDraw {
19 |
20 | private Paint mRSI1Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
21 | private Paint mRSI2Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
22 | private Paint mRSI3Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
23 |
24 | public RSIDraw(BaseKLineChartView view) {
25 |
26 | }
27 |
28 | @Override
29 | public void drawTranslated(@Nullable IRSI lastPoint, @NonNull IRSI curPoint,
30 | float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position) {
31 | if (lastPoint.getRsi() != 0) {
32 | view.drawChildLine(canvas, mRSI1Paint, lastX, lastPoint.getRsi(), curX, curPoint.getRsi());
33 | }
34 | }
35 |
36 | @Override
37 | public void drawText(@NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position, float x, float y) {
38 | IRSI point = (IRSI) view.getItem(position);
39 | if (point.getRsi() != 0) {
40 | String text = "RSI(14) ";
41 | canvas.drawText(text, x, y, view.getTextPaint());
42 | x += view.getTextPaint().measureText(text);
43 | text = view.formatValue(point.getRsi());
44 | canvas.drawText(text, x, y, mRSI1Paint);
45 | }
46 | }
47 |
48 | @Override
49 | public float getMaxValue(IRSI point) {
50 | return point.getRsi();
51 | }
52 |
53 | @Override
54 | public float getMinValue(IRSI point) {
55 | return point.getRsi();
56 | }
57 |
58 | @Override
59 | public IValueFormatter getValueFormatter() {
60 | return new ValueFormatter();
61 | }
62 |
63 | public void setRSI1Color(int color) {
64 | mRSI1Paint.setColor(color);
65 | }
66 |
67 | public void setRSI2Color(int color) {
68 | mRSI2Paint.setColor(color);
69 | }
70 |
71 | public void setRSI3Color(int color) {
72 | mRSI3Paint.setColor(color);
73 | }
74 |
75 | /**
76 | * 设置曲线宽度
77 | */
78 | public void setLineWidth(float width) {
79 | mRSI1Paint.setStrokeWidth(width);
80 | mRSI2Paint.setStrokeWidth(width);
81 | mRSI3Paint.setStrokeWidth(width);
82 | }
83 |
84 | /**
85 | * 设置文字大小
86 | */
87 | public void setTextSize(float textSize) {
88 | mRSI2Paint.setTextSize(textSize);
89 | mRSI3Paint.setTextSize(textSize);
90 | mRSI1Paint.setTextSize(textSize);
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/draw/Status.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.draw;
2 |
3 | /**
4 | * @author fujianlian Created on 2018/8/20 11:09
5 | * @descripe MainDraw当前子视图
6 | */
7 | public enum Status {
8 | MA, BOLL, NONE
9 | }
10 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/draw/VolumeDraw.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.draw;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.content.ContextCompat;
9 |
10 | import com.github.fujianlian.klinechart.R;
11 | import com.github.fujianlian.klinechart.BaseKLineChartView;
12 | import com.github.fujianlian.klinechart.base.IChartDraw;
13 | import com.github.fujianlian.klinechart.base.IValueFormatter;
14 | import com.github.fujianlian.klinechart.entity.IVolume;
15 | import com.github.fujianlian.klinechart.formatter.BigValueFormatter;
16 | import com.github.fujianlian.klinechart.utils.ViewUtil;
17 |
18 | /**
19 | * Created by hjm on 2017/11/14 17:49.
20 | */
21 | public class VolumeDraw implements IChartDraw {
22 |
23 | private Paint mRedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
24 | private Paint mGreenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
25 | private Paint ma5Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
26 | private Paint ma10Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
27 | private int pillarWidth = 0;
28 |
29 | public VolumeDraw(BaseKLineChartView view) {
30 | Context context = view.getContext();
31 | mRedPaint.setColor(ContextCompat.getColor(context, R.color.chart_red));
32 | mGreenPaint.setColor(ContextCompat.getColor(context, R.color.chart_green));
33 | pillarWidth = ViewUtil.Dp2Px(context, 4);
34 | }
35 |
36 | @Override
37 | public void drawTranslated(
38 | @Nullable IVolume lastPoint, @NonNull IVolume curPoint, float lastX, float curX,
39 | @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position) {
40 |
41 | drawHistogram(canvas, curPoint, lastPoint, curX, view, position);
42 | if (lastPoint.getMA5Volume() != 0f) {
43 | view.drawVolLine(canvas, ma5Paint, lastX, lastPoint.getMA5Volume(), curX, curPoint.getMA5Volume());
44 | }
45 | if (lastPoint.getMA10Volume() != 0f) {
46 | view.drawVolLine(canvas, ma10Paint, lastX, lastPoint.getMA10Volume(), curX, curPoint.getMA10Volume());
47 | }
48 | }
49 |
50 | private void drawHistogram(
51 | Canvas canvas, IVolume curPoint, IVolume lastPoint, float curX,
52 | BaseKLineChartView view, int position) {
53 |
54 | float r = pillarWidth / 2;
55 | float top = view.getVolY(curPoint.getVolume());
56 | int bottom = view.getVolRect().bottom;
57 | if (curPoint.getClosePrice() >= curPoint.getOpenPrice()) {//涨
58 | canvas.drawRect(curX - r, top, curX + r, bottom,mGreenPaint);
59 | } else {
60 | canvas.drawRect(curX - r, top, curX + r, bottom, mRedPaint);
61 | }
62 |
63 | }
64 |
65 | @Override
66 | public void drawText(
67 | @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position, float x, float y) {
68 | IVolume point = (IVolume) view.getItem(position);
69 | String text = "VOL";
70 | // String text = "VOL:" + getValueFormatter().format(point.getVolume()) + " ";
71 | // canvas.drawText(text, x, y, view.getTextPaint());
72 | // x += view.getTextPaint().measureText(text);
73 | // text = "MA5:" + getValueFormatter().format(point.getMA5Volume()) + " ";
74 | // canvas.drawText(text, x, y, ma5Paint);
75 | // x += ma5Paint.measureText(text);
76 | // text = "MA10:" + getValueFormatter().format(point.getMA10Volume());
77 | canvas.drawText(text, x, y, ma10Paint);
78 | }
79 |
80 | @Override
81 | public float getMaxValue(IVolume point) {
82 | return Math.max(point.getVolume(), Math.max(point.getMA5Volume(), point.getMA10Volume()));
83 | }
84 |
85 | @Override
86 | public float getMinValue(IVolume point) {
87 | return Math.min(point.getVolume(), Math.min(point.getMA5Volume(), point.getMA10Volume()));
88 | }
89 |
90 | @Override
91 | public IValueFormatter getValueFormatter() {
92 | return new BigValueFormatter();
93 | }
94 |
95 | /**
96 | * 设置 MA5 线的颜色
97 | *
98 | * @param color
99 | */
100 | public void setMa5Color(int color) {
101 | this.ma5Paint.setColor(color);
102 | }
103 |
104 | /**
105 | * 设置 MA10 线的颜色
106 | *
107 | * @param color
108 | */
109 | public void setMa10Color(int color) {
110 | this.ma10Paint.setColor(color);
111 | }
112 |
113 | public void setLineWidth(float width) {
114 | this.ma5Paint.setStrokeWidth(width);
115 | this.ma10Paint.setStrokeWidth(width);
116 | }
117 |
118 | /**
119 | * 设置文字大小
120 | *
121 | * @param textSize
122 | */
123 | public void setTextSize(float textSize) {
124 | this.ma5Paint.setTextSize(textSize);
125 | this.ma10Paint.setTextSize(textSize);
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/draw/WRDraw.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.draw;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 |
8 | import com.github.fujianlian.klinechart.BaseKLineChartView;
9 | import com.github.fujianlian.klinechart.base.IChartDraw;
10 | import com.github.fujianlian.klinechart.base.IValueFormatter;
11 | import com.github.fujianlian.klinechart.entity.IWR;
12 | import com.github.fujianlian.klinechart.formatter.ValueFormatter;
13 |
14 | /**
15 | * KDJ实现类
16 | * Created by tifezh on 2016/6/19.
17 | */
18 | public class WRDraw implements IChartDraw {
19 |
20 | private Paint mRPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
21 |
22 | public WRDraw(BaseKLineChartView view) {
23 | }
24 |
25 | @Override
26 | public void drawTranslated(@Nullable IWR lastPoint, @NonNull IWR curPoint, float lastX,
27 | float curX, @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position) {
28 | if (lastPoint.getR() != -10) {
29 | view.drawChildLine(canvas, mRPaint, lastX, lastPoint.getR(), curX, curPoint.getR());
30 | }
31 | }
32 |
33 | @Override
34 | public void drawText(@NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position, float x, float y) {
35 | IWR point = (IWR) view.getItem(position);
36 | if (point.getR() != -10) {
37 | String text = "WR(14):";
38 | canvas.drawText(text, x, y, view.getTextPaint());
39 | x += view.getTextPaint().measureText(text);
40 | text = view.formatValue(point.getR()) + " ";
41 | canvas.drawText(text, x, y, mRPaint);
42 | }
43 | }
44 |
45 | @Override
46 | public float getMaxValue(IWR point) {
47 | return point.getR();
48 | }
49 |
50 | @Override
51 | public float getMinValue(IWR point) {
52 | return point.getR();
53 | }
54 |
55 | @Override
56 | public IValueFormatter getValueFormatter() {
57 | return new ValueFormatter();
58 | }
59 |
60 | /**
61 | * 设置%R颜色
62 | */
63 | public void setRColor(int color) {
64 | mRPaint.setColor(color);
65 | }
66 |
67 | /**
68 | * 设置曲线宽度
69 | */
70 | public void setLineWidth(float width) {
71 | mRPaint.setStrokeWidth(width);
72 | }
73 |
74 | /**
75 | * 设置文字大小
76 | */
77 | public void setTextSize(float textSize) {
78 | mRPaint.setTextSize(textSize);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/ICandle.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | /**
4 | * 蜡烛图实体接口
5 | * Created by tifezh on 2016/6/9.
6 | */
7 | public interface ICandle {
8 |
9 | /**
10 | * 开盘价
11 | */
12 | float getOpenPrice();
13 |
14 | /**
15 | * 最高价
16 | */
17 | float getHighPrice();
18 |
19 | /**
20 | * 最低价
21 | */
22 | float getLowPrice();
23 |
24 | /**
25 | * 收盘价
26 | */
27 | float getClosePrice();
28 |
29 |
30 | // 以下为MA数据
31 | /**
32 | * 五(月,日,时,分,5分等)均价
33 | */
34 | float getMA5Price();
35 |
36 | /**
37 | * 十(月,日,时,分,5分等)均价
38 | */
39 | float getMA10Price();
40 |
41 | /**
42 | * 二十(月,日,时,分,5分等)均价
43 | */
44 | float getMA20Price();
45 |
46 | /**
47 | * 三十(月,日,时,分,5分等)均价
48 | */
49 | float getMA30Price();
50 |
51 | /**
52 | * 六十(月,日,时,分,5分等)均价
53 | */
54 | float getMA60Price();
55 |
56 | // 以下为BOLL数据
57 | /**
58 | * 上轨线
59 | */
60 | float getUp();
61 |
62 | /**
63 | * 中轨线
64 | */
65 | float getMb();
66 |
67 | /**
68 | * 下轨线
69 | */
70 | float getDn();
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/IKDJ.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | /**
4 | * @author fujianlian Created on 2018/8/20 16:08
5 | * @descripe KDJ指标(随机指标)接口
6 | * 相关说明:https://baike.baidu.com/item/KDJ%E6%8C%87%E6%A0%87/6328421?fr=aladdin&fromid=3423560&fromtitle=kdj
7 | */
8 | public interface IKDJ {
9 |
10 | /**
11 | * K值
12 | */
13 | float getK();
14 |
15 | /**
16 | * D值
17 | */
18 | float getD();
19 |
20 | /**
21 | * J值
22 | */
23 | float getJ();
24 |
25 | }
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/IKLine.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | /**
4 | * KDJ指标(随机指标)接口
5 | * Created by tifezh on 2016/6/9.
6 | */
7 | public interface IKLine extends ICandle, IMACD, IKDJ, IRSI, IVolume, IWR {
8 | }
9 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/IMACD.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | /**
4 | * MACD指标(指数平滑移动平均线)接口
5 | * @see 相关说明
6 | * Created by tifezh on 2016/6/10.
7 | */
8 |
9 | public interface IMACD {
10 |
11 |
12 | /**
13 | * DEA值
14 | */
15 | float getDea();
16 |
17 | /**
18 | * DIF值
19 | */
20 | float getDif();
21 |
22 | /**
23 | * MACD值
24 | */
25 | float getMacd();
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/IRSI.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | /**
4 | * RSI指标接口
5 | * @see 相关说明
6 | * Created by tifezh on 2016/6/10.
7 | */
8 |
9 | public interface IRSI {
10 |
11 | /**
12 | * RSI值
13 | */
14 | float getRsi();
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/IVolume.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | /**
4 | * 成交量接口
5 | * Created by hjm on 2017/11/14 17:46.
6 | */
7 |
8 | public interface IVolume {
9 |
10 | /**
11 | * 开盘价
12 | */
13 | float getOpenPrice();
14 |
15 | /**
16 | * 收盘价
17 | */
18 | float getClosePrice();
19 |
20 | /**
21 | * 成交量
22 | */
23 | float getVolume();
24 |
25 | /**
26 | * 五(月,日,时,分,5分等)均量
27 | */
28 | float getMA5Volume();
29 |
30 | /**
31 | * 十(月,日,时,分,5分等)均量
32 | */
33 | float getMA10Volume();
34 | }
35 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/IWR.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | /**
4 | * @author fujianlian Created on 2018/8/20 15:16
5 | * @descripe WR指标(随机指标)接口
6 | */
7 | public interface IWR {
8 |
9 | /**
10 | * %R值
11 | */
12 | float getR();
13 |
14 | }
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/entity/OrderEntity.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.entity;
2 |
3 | public class OrderEntity {
4 | private long orderTimeStamp;
5 | private long orderStopTimeStamp;
6 | private String amount;
7 | private boolean isUp;
8 |
9 |
10 | public String getAmount() {
11 | return amount;
12 | }
13 |
14 | public void setAmount(String amount) {
15 | this.amount = amount;
16 | }
17 |
18 | public long getOrderTimeStamp() {
19 | return orderTimeStamp;
20 | }
21 |
22 | public void setOrderTimeStamp(long orderTimeStamp) {
23 | this.orderTimeStamp = orderTimeStamp;
24 | }
25 |
26 | public long getOrderStopTimeStamp() {
27 | return orderStopTimeStamp;
28 | }
29 |
30 | public void setOrderStopTimeStamp(long orderStopTimeStamp) {
31 | this.orderStopTimeStamp = orderStopTimeStamp;
32 | }
33 |
34 |
35 | public boolean isUp() {
36 | return isUp;
37 | }
38 |
39 | public void setUp(boolean up) {
40 | isUp = up;
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return "OrderEntity{" +
46 | "orderTimeStamp=" + orderTimeStamp +
47 | ", orderStopTimeStamp=" + orderStopTimeStamp +
48 | ", amount='" + amount + '\'' +
49 | ", isUp=" + isUp +
50 | '}';
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/formatter/BigValueFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.formatter;
2 |
3 | import com.github.fujianlian.klinechart.base.IValueFormatter;
4 |
5 | import java.util.Locale;
6 |
7 | /**
8 | * 对较大数据进行格式化
9 | * Created by tifezh on 2017/12/13.
10 | */
11 |
12 | public class BigValueFormatter implements IValueFormatter {
13 |
14 | //必须是排好序的
15 | private int[] values = {10000, 1000000, 100000000};
16 | private String[] units = {"万", "百万", "亿"};
17 |
18 | @Override
19 | public String format(float value, int digit) {
20 | String unit = "";
21 | int i = values.length - 1;
22 | while (i >= 0) {
23 | if (value > values[i]) {
24 | value /= values[i];
25 | unit = units[i];
26 | break;
27 | }
28 | i--;
29 | }
30 | return String.format(Locale.getDefault(), "%.2f", value) + unit;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/formatter/DateFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.formatter;
2 |
3 | import com.github.fujianlian.klinechart.base.IDateTimeFormatter;
4 | import com.github.fujianlian.klinechart.utils.DateUtil;
5 |
6 | import java.util.Date;
7 |
8 |
9 | /**
10 | * 时间格式化器
11 | * Created by tifezh on 2016/6/21.
12 | */
13 |
14 | public class DateFormatter implements IDateTimeFormatter {
15 | @Override
16 | public String format(Date date) {
17 | if (date != null) {
18 | return DateUtil.DateFormat.format(date);
19 | } else {
20 | return "";
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/formatter/TimeFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.formatter;
2 |
3 | import com.github.fujianlian.klinechart.base.IDateTimeFormatter;
4 | import com.github.fujianlian.klinechart.utils.DateUtil;
5 |
6 | import java.util.Date;
7 |
8 |
9 | /**
10 | * 时间格式化器
11 | * Created by tifezh on 2016/6/21.
12 | */
13 |
14 | public class TimeFormatter implements IDateTimeFormatter {
15 | @Override
16 | public String format(Date date) {
17 | if (date == null) {
18 | return "";
19 | }
20 | return DateUtil.shortTimeFormat.format(date);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/formatter/ValueFormatter.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.formatter;
2 |
3 | import com.github.fujianlian.klinechart.base.IValueFormatter;
4 |
5 | /**
6 | * Value格式化类
7 | * Created by tifezh on 2016/6/21.
8 | */
9 |
10 | public class ValueFormatter implements IValueFormatter {
11 |
12 |
13 | @Override
14 | public String format(float value, int digit) {
15 | return String.format("%." + digit + "f", value);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/utils/Constants.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.utils;
2 |
3 | public class Constants {
4 |
5 |
6 | /**
7 | * case R.id.tv_ma:
8 | * setChildDraw(0);
9 | * break;
10 | * case R.id.tv_boll:
11 | * setChildDraw(1);
12 | * break;
13 | * case R.id.tv_macd:
14 | * setChildDraw(2);
15 | * break;
16 | * case R.id.tv_kdj:
17 | * setChildDraw(3);
18 | * break;
19 | * case R.id.tv_rsi:
20 | * setChildDraw(4);
21 | * break;
22 | * case R.id.tv_vol:
23 | * setChildDraw(5);
24 | * break;
25 | * case R.id.tv_clear:
26 | * setChildDraw(6);
27 | * break;
28 | */
29 | public static final int MA = 0;
30 | public static final int BOLL = 1;
31 | public static final int MACD = 2;
32 | public static final int KDJ = 3;
33 | public static final int RSI = 4;
34 | public static final int VOL = 5;
35 | public static final int CLEAR = 6;
36 |
37 | public static String CURRENT_LINE_TYPE = "RANG_TYPE";
38 | public static final String RANG_TYPE = "RANG_TYPE";
39 | public static final String LINE_TYPE = "LINE_TYPE";
40 | public static final String CANDLE_TYPE = "CANDLE_TYPE";
41 | public static final int RANG_ITEM = 30; //添加假数据实现k线左移
42 |
43 | //"1min", "5min", "15min", "30min", "60min", "1day", "1week", "1mon"};
44 | public static final String FIVE_SECOND = "5s";
45 | public static final String ONE_MINUTE = "1min";
46 | public static final String FIVE_MINUTE = "5min";
47 | public static final String FIFTEEN_MINUTE = "15min";
48 | public static final String THIRTY_MINUTE = "30min";
49 | public static final String SIXTY_MINUTE = "60min";
50 | public static final String ONE_DAY = "1day";
51 | public static final String ONE_WEEK = "1week";
52 | public static final String ONE_MON = "1mon";
53 | }
54 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/utils/DateUtil.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.utils;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 | import java.util.Locale;
8 |
9 | /**
10 | * 时间工具类
11 | * Created by tifezh on 2016/4/27.
12 | */
13 | public class DateUtil {
14 | public static SimpleDateFormat longTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
15 | public static SimpleDateFormat shortTimeFormat = new SimpleDateFormat("HH:mm");
16 | public static SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy/MM/dd");
17 | private static String timeString;
18 | private static DatePattern pattern;
19 |
20 |
21 | /**
22 | * 枚举日期格式
23 | *
24 | * @author Administrator
25 | */
26 | public enum DatePattern {
27 | /**
28 | * 格式:"yyyy-MM-dd HH:mm:ss"
29 | */
30 | ALL_TIME {
31 | public String getValue() {
32 | return "yyyy-MM-dd HH:mm:ss";
33 | }
34 | },
35 | /**
36 | * 格式:"yyyy-MM"
37 | */
38 | ONLY_MONTH {
39 | public String getValue() {
40 | return "yyyy-MM";
41 | }
42 | },
43 | /**
44 | * 格式:"yyyy-MM-dd"
45 | */
46 | ONLY_DAY {
47 | public String getValue() {
48 | return "yyyy-MM-dd";
49 | }
50 | },
51 | /**
52 | * 格式:"yyyy-MM-dd HH"
53 | */
54 | ONLY_HOUR {
55 | public String getValue() {
56 | return "yyyy-MM-dd HH";
57 | }
58 | },
59 | /**
60 | * 格式:"yyyy-MM-dd HH:mm"
61 | */
62 | ONLY_MINUTE {
63 | public String getValue() {
64 | return "yyyy-MM-dd HH:mm";
65 | }
66 | },
67 | /**
68 | * 格式:"MM-dd"
69 | */
70 | ONLY_MONTH_DAY {
71 | public String getValue() {
72 | return "MM-dd";
73 | }
74 | },
75 | /**
76 | * 格式:"MM-dd HH:mm"
77 | */
78 | ONLY_MONTH_SEC {
79 | public String getValue() {
80 | return "MM-dd HH:mm";
81 | }
82 | },
83 | /**
84 | * 格式:"MM-dd HH:mm"
85 | */
86 | ONLY_MONTH_ALL_SEC {
87 | public String getValue() {
88 | return "MM-dd HH:mm:ss";
89 | }
90 | },
91 | /**
92 | * 格式:"HH:mm:ss"
93 | */
94 | ONLY_TIME {
95 | public String getValue() {
96 | return "HH:mm:ss";
97 | }
98 | },
99 | /**
100 | * 格式:"HH:mm"
101 | */
102 | ONLY_HOUR_MINUTE {
103 | public String getValue() {
104 | return "HH:mm";
105 | }
106 | },
107 | /**
108 | * 格式:"ss"
109 | */
110 | ONLY_SECOND {
111 | public String getValue() {
112 | return "ss";
113 | }
114 | };
115 |
116 | public abstract String getValue();
117 | }
118 |
119 | //字符串转时间戳
120 | public static String getTime(String timeString, DatePattern pattern) {
121 | String timeStamp = null;
122 | SimpleDateFormat sdf = new SimpleDateFormat(pattern.getValue());
123 | Date d;
124 | try {
125 | d = sdf.parse(timeString);
126 | long l = d.getTime();
127 | timeStamp = String.valueOf(l);
128 | } catch (ParseException e) {
129 | e.printStackTrace();
130 | }
131 | return timeStamp;
132 | }
133 |
134 | //时间戳转字符串
135 | public static String getStrTime(String timeStamp, DatePattern pattern) {
136 | String timeString = null;
137 | SimpleDateFormat sdf = new SimpleDateFormat(pattern.getValue());
138 | long l = Long.valueOf(timeStamp);
139 | timeString = sdf.format(new Date(l));//单位秒
140 | return timeString;
141 | }
142 |
143 |
144 | private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
145 |
146 | private DateUtil() {
147 | }
148 |
149 | ;
150 |
151 |
152 | /**
153 | * 往后推移时间
154 | *
155 | * @param date
156 | * @param minute
157 | * @return
158 | * @throws ParseException
159 | */
160 | public static String dealTime(String date, int minute) throws ParseException {
161 | SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
162 | Date d = sd.parse(date);
163 | // 把当前得到的时间用date.getTime()的方法写成时间戳的形式,再加上8小时对应的毫秒数
164 | long rightTime = (d.getTime() + minute * 60 * 1000);
165 | // 把得到的新的时间戳再次格式化成时间的格式
166 | String newtime = sd.format(rightTime);
167 | return sd.parse(newtime).getTime() + "";
168 |
169 | }
170 |
171 |
172 | /**
173 | * 将时分秒转换成时分
174 | *
175 | * @param time hh:mm:ss
176 | * @return hh:mm
177 | */
178 | public static String getOnlyMinute(String time) {
179 | if (time.length() > 5)
180 | return time.substring(0, time.length() - 3);
181 | else return "";
182 | }
183 |
184 | /**
185 | * 获取当前时间
186 | *
187 | * @return 返回当前时间,格式2015-12-3 10:54:21
188 | */
189 | public static String getNowDate(DatePattern pattern) {
190 | String dateString = null;
191 | Calendar calendar = Calendar.getInstance();
192 | Date dateNow = calendar.getTime();
193 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.getValue(), Locale.CHINA);
194 | dateString = simpleDateFormat.format(dateNow);
195 | return dateString;
196 | }
197 |
198 | /**
199 | * 获取当前时间戳
200 | *
201 | * @return 返回当前时间,格式2015-12-3
202 | */
203 | public static Date getNowDate(String year, String month, String day) {
204 | Date date = null;
205 | try {
206 | date = sdf.parse(year + month + day);
207 | } catch (Exception e) {
208 | e.printStackTrace();
209 | }
210 | return date;
211 | }
212 |
213 | /**
214 | * 将一个日期字符串转换成Data对象
215 | *
216 | * @param dateString 日期字符串
217 | * @param pattern 转换格式
218 | * @return 返回转换后的日期对象
219 | */
220 | public static Date stringToDate(String dateString, DatePattern pattern) {
221 | Date date = null;
222 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.getValue(), Locale.CHINA);
223 | try {
224 | date = simpleDateFormat.parse(dateString);
225 | } catch (ParseException e) {
226 | e.printStackTrace();
227 | }
228 | return date;
229 | }
230 |
231 | /**
232 | * 将date转换成字符串
233 | *
234 | * @param date 日期
235 | * @param pattern 日期的目标格式
236 | * @return
237 | */
238 | public static String dateToString(Date date, DatePattern pattern) {
239 | String string = "";
240 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.getValue(), Locale.CHINA);
241 | string = simpleDateFormat.format(date);
242 | return string;
243 | }
244 |
245 | /**
246 | * 获取时间差 返回单位分钟
247 | *
248 | * @param start
249 | * @return
250 | */
251 | public static int getSpaceTime(long start) {
252 | long end = System.currentTimeMillis();
253 | int minute = (int) ((start * 1000 - end) / 1000 / 60);
254 | return minute;
255 | }
256 |
257 | /**
258 | * 获取指定日期周几
259 | *
260 | * @param date 指定日期
261 | * @return 返回值为: "周日", "周一", "周二", "周三", "周四", "周五", "周六"
262 | */
263 | public static String getWeekOfDate(Date date) {
264 | String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
265 | Calendar calendar = Calendar.getInstance();
266 | calendar.setTime(date);
267 | int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
268 | if (week < 0)
269 | week = 0;
270 | return weekDays[week];
271 | }
272 |
273 | /**
274 | * 获取指定日期对应周几的序列
275 | *
276 | * @param date 指定日期
277 | * @return 周一:1 周二:2 周三:3 周四:4 周五:5 周六:6 周日:7
278 | */
279 | public static int getIndexWeekOfDate(Date date) {
280 | // Calendar calendar = Calendar.getInstance();
281 | // calendar.setTime(date);
282 | // int index = calendar.get(Calendar.DAY_OF_WEEK);
283 | // if(index == 1){
284 | // return 7;
285 | // }else{
286 | // return --index;
287 | // }
288 | Calendar now = Calendar.getInstance();
289 | //一周第一天是否为星期天
290 | boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY);
291 | //获取周几
292 | int weekDay = now.get(Calendar.DAY_OF_WEEK);
293 | //若一周第一天为星期天,则-1
294 | if (isFirstSunday) {
295 | weekDay = weekDay - 1;
296 | if (weekDay == 0) {
297 | weekDay = 7;
298 | }
299 | }
300 | return weekDay;
301 | //若当天为2014年10月13日(星期一),则打印输出:1
302 | //若当天为2014年10月17日(星期五),则打印输出:5
303 | //若当天为2014年10月19日(星期日),则打印输出:7
304 | }
305 |
306 |
307 | //获取当前月的第一天
308 | public static String getMonthStartDate(DatePattern datePattern) {
309 | // SimpleDateFormat dateFormater = new SimpleDateFormat(
310 | // "yyyy-MM-dd");
311 | SimpleDateFormat dateFormater = new SimpleDateFormat(
312 | datePattern.getValue());
313 | Calendar cal = Calendar.getInstance();
314 | cal.set(Calendar.DAY_OF_MONTH, 1);
315 | cal.getTime();
316 | return dateFormater.format(cal.getTime()) + "";
317 |
318 | }
319 |
320 | //获取当前月的最后一天
321 | public static String getMonthEndDate(DatePattern datePattern) {
322 | SimpleDateFormat dateFormater = new SimpleDateFormat(
323 | datePattern.getValue());
324 | Calendar cal = Calendar.getInstance();
325 | cal.set(Calendar.DAY_OF_MONTH,
326 | cal.getActualMaximum(Calendar.DAY_OF_MONTH));
327 | return dateFormater.format(cal.getTime());
328 | }
329 |
330 | /**
331 | * 返回当前月份
332 | *
333 | * @return
334 | */
335 | public static int getNowMonth() {
336 | Calendar calendar = Calendar.getInstance();
337 | return calendar.get(Calendar.MONTH) + 1;
338 | }
339 |
340 | /**
341 | * 获取当前月号
342 | *
343 | * @return
344 | */
345 | public static int getNowDay() {
346 | Calendar calendar = Calendar.getInstance();
347 | return calendar.get(Calendar.DATE);
348 | }
349 |
350 | /**
351 | * 获取当前年份
352 | *
353 | * @return
354 | */
355 | public static int getNowYear() {
356 | Calendar calendar = Calendar.getInstance();
357 | return calendar.get(Calendar.YEAR);
358 | }
359 |
360 | /**
361 | * 获取当前小时
362 | *
363 | * @return
364 | */
365 | public static int getNowHour() {
366 | Calendar calendar = Calendar.getInstance();
367 | return calendar.get(Calendar.HOUR);
368 | }
369 |
370 | /**
371 | * 获取当前分钟
372 | *
373 | * @return
374 | */
375 | public static int getNowMinute() {
376 | Calendar calendar = Calendar.getInstance();
377 | return calendar.get(Calendar.MINUTE);
378 | }
379 |
380 | /**
381 | * 数据补0 如8月 返回08 9号返回09
382 | *
383 | * @param number
384 | * @return
385 | */
386 | public static String getTwoDigitNumber(int number) {
387 | if (number < 10) {
388 | return "0" + number;
389 | } else {
390 | return number + "";
391 | }
392 | }
393 |
394 | /**
395 | * 获取本月份的天数
396 | *
397 | * @param
398 | * @param
399 | * @return
400 | */
401 | public static int getNowDaysOfMonth() {
402 | Calendar calendar = Calendar.getInstance();
403 | return daysOfMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.DATE) + 1);
404 | }
405 |
406 | /**
407 | * 获取指定月份的天数
408 | *
409 | * @param year 年份
410 | * @param month 月份
411 | * @return 对应天数
412 | */
413 | public static int daysOfMonth(int year, int month) {
414 | switch (month) {
415 | case 1:
416 | case 3:
417 | case 5:
418 | case 7:
419 | case 8:
420 | case 10:
421 | case 12:
422 | return 31;
423 | case 4:
424 | case 6:
425 | case 9:
426 | case 11:
427 | return 30;
428 | case 2:
429 | if ((year % 4 == 0 && year % 100 == 0) || year % 400 == 0) {
430 | return 29;
431 | } else {
432 | return 28;
433 | }
434 | default:
435 | return -1;
436 | }
437 | }
438 |
439 |
440 | /**
441 | * 推移时间
442 | *
443 | * @param stDate 被推移的当前时间
444 | * @param pattern 当前时间的时间格式 yyyy:MM:dd
445 | * @param amount 需要推移的天数 (1为 后一天 -1为前一天)
446 | * @return
447 | */
448 | public static String dateOfMove(String stDate, int amount, DatePattern pattern) {
449 | if (stDate == null)
450 | return null;
451 | Calendar c = Calendar.getInstance();
452 | Date date = stringToDate(stDate, pattern);
453 | c.setTime(date);
454 | c.add(Calendar.DAY_OF_MONTH, amount);// 今天+1天
455 | Date tomorrow = c.getTime();
456 | return dateToString(tomorrow, pattern);
457 | }
458 |
459 | /**
460 | * 推移时间
461 | *
462 | * @param stDate 被推移的当前时间
463 | * @param amount 需要推移的天数 (1为 后一天 -1为前一天)
464 | * @return
465 | */
466 | public static Date dateOfMove(Date stDate, int amount) {
467 | if (stDate == null)
468 | return null;
469 | Calendar c = Calendar.getInstance();
470 | c.setTime(stDate);
471 | c.add(Calendar.DAY_OF_MONTH, amount);// 今天+1天
472 | Date tomorrow = c.getTime();
473 | return tomorrow;
474 | }
475 |
476 |
477 | // a integer to xx:xx:xx 将秒转换为时分秒的字符串
478 | public static String secToTime(long time) {
479 | String timeStr = null;
480 | long hour = 0;
481 | long minute = 0;
482 | long second = 0;
483 | if (time <= 0)
484 | return "00:00";
485 | else {
486 | minute = time / 60;
487 | if (minute < 60) {
488 | second = time % 60;
489 | timeStr = unitFormat(minute) + ":" + unitFormat(second);
490 | } else {
491 | hour = minute / 60;
492 | if (hour > 99)
493 | return "99:59:59";
494 | minute = minute % 60;
495 | second = time - hour * 3600 - minute * 60;
496 | timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
497 | }
498 | }
499 | return timeStr;
500 | }
501 |
502 | public static String unitFormat(long i) {
503 | String retStr = null;
504 | if (i >= 0 && i < 10)
505 | retStr = "0" + Long.toString(i);
506 | else
507 | retStr = "" + i;
508 | return retStr;
509 | }
510 |
511 | /**
512 | * 毫秒转换为 天数 小数数 分钟数 xx
513 | *
514 | * @param nmMillSecond
515 | * @return
516 | */
517 | public static MyTimeBean millSecondToTimeBean(long nmMillSecond) {
518 | MyTimeBean myTimeBean = new MyTimeBean();
519 | long millSecond = nmMillSecond % 1000 / 10;
520 | myTimeBean.setMillSecond(millSecond + "");
521 | nmMillSecond = nmMillSecond / 1000;
522 | long days = nmMillSecond / (60 * 60 * 24);
523 |
524 | //long hours = (nmMillSecond % ( 60 * 60 * 24)) / (60 * 60);
525 | long hour;
526 | if (days > 0) {
527 | hour = (nmMillSecond % (60 * 60 * 24)) / (60 * 60);//时
528 | } else {
529 | hour = nmMillSecond / 3600;//时
530 | }
531 | long minutes = (nmMillSecond % (60 * 60)) / 60;
532 | long seconds = nmMillSecond % 60;
533 |
534 | myTimeBean.setSecond(seconds + "");
535 | myTimeBean.setMinute(minutes + "");
536 | myTimeBean.setHour(hour + "");
537 | myTimeBean.setDay(days + "");
538 | return myTimeBean;
539 | }
540 |
541 | /**
542 | * 毫秒转天数+小时数+分钟数+秒数+毫秒数
543 | */
544 | public static class MyTimeBean {
545 | String day;
546 | String hour;
547 | String minute;
548 | String second;
549 | String millSecond;
550 |
551 | public MyTimeBean() {
552 | }
553 |
554 | public String getDay() {
555 | return day;
556 | }
557 |
558 | public void setDay(String day) {
559 | this.day = day;
560 | }
561 |
562 | public String getHour() {
563 | return hour;
564 | }
565 |
566 | public void setHour(String hour) {
567 | this.hour = hour;
568 | }
569 |
570 | public String getMinute() {
571 | return minute;
572 | }
573 |
574 | public void setMinute(String minute) {
575 | this.minute = minute;
576 | }
577 |
578 | public String getSecond() {
579 | return second;
580 | }
581 |
582 | public void setSecond(String second) {
583 | this.second = second;
584 | }
585 |
586 | public String getMillSecond() {
587 | return millSecond;
588 | }
589 |
590 | public void setMillSecond(String millSecond) {
591 | this.millSecond = millSecond;
592 | }
593 | }
594 | }
595 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/java/com/github/fujianlian/klinechart/utils/ViewUtil.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart.utils;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Created by tian on 2016/4/11.
7 | */
8 | public class ViewUtil {
9 | static public int Dp2Px(Context context, float dp) {
10 | final float scale = context.getResources().getDisplayMetrics().density;
11 | return (int) (dp * scale + 0.5f);
12 | }
13 |
14 | static public int Px2Dp(Context context, float px) {
15 | final float scale = context.getResources().getDisplayMetrics().density;
16 | return (int) (px / scale + 0.5f);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/ic_down_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/KLineChartLib/src/main/res/drawable/ic_down_order.png
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/ic_point_kline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/KLineChartLib/src/main/res/drawable/ic_point_kline.png
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/ic_start_time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/KLineChartLib/src/main/res/drawable/ic_start_time.png
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/ic_stop_time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/KLineChartLib/src/main/res/drawable/ic_stop_time.png
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/ic_target_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/KLineChartLib/src/main/res/drawable/ic_target_normal.png
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/ic_target_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/KLineChartLib/src/main/res/drawable/ic_target_pressed.png
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/ic_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/KLineChartLib/src/main/res/drawable/ic_up.png
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/selector_button_target.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/drawable/shape_rectangle_with.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
8 |
9 | #D04B63
10 | #FF8A7C
11 | #6384FF
12 | #E8D28E
13 | #57BEB1
14 | #53B4A9
15 | #53B4A9
16 |
17 | #5498FF
18 | #00ffffff
19 |
20 | #445498FF
21 | #6384FF
22 |
23 | #DA8AE5
24 | #39B0E8
25 | #FFC76D
26 | #ffffff
27 | #53B4A9
28 |
29 | #202326
30 | #111622
31 | #202326
32 | #662B2D52
33 | #818596
34 | #882E3546
35 | #30343C
36 | #3F51B5
37 | #FF6601
38 | #111622
39 |
40 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 10sp
3 | 12sp
4 | 1dp
5 | 6dp
6 | 1dp
7 | 0.8dp
8 | 0.5dp
9 | 7dp
10 | 15dp
11 | 15dp
12 | 10dp
13 |
--------------------------------------------------------------------------------
/KLineChartLib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | KlineChartView
4 |
5 |
6 | 注册
7 | 登录
8 | 请输入账号
9 | 请输入密码
10 | 获取验证码
11 | 验证码登录
12 | 请输入验证码
13 | 请输入邀请码
14 | 用户名
15 | 未实名认证
16 | 充值/入金
17 | 提现/出金
18 | 账户管理
19 | 交易记录
20 | 出金记录
21 | 入金记录
22 | 订单交易记录
23 | 退出账号
24 | DCF账户
25 | 银行卡
26 | 模拟账户
27 | 充值
28 | 欢迎来到DCF
29 | 注册领取5000USDT模拟金
30 | 密码不记得了,点击忘记密码
31 | 领取5000USDT模拟金
32 | 通过注册,已表示同意【条款与要求】
33 | 个人信息
34 | 启动页
35 | 请输入姓名
36 | 姓名
37 | 证件
38 | 身份证
39 | 护照
40 | 证件号码
41 | 银行卡号
42 | 请输入手机号
43 | 预留手机号
44 | 手机号
45 | 证件地址
46 | 未实名认证
47 | 用户名
48 | 姓名
49 | 国家
50 | 省份
51 | 城市
52 | 1分
53 | 时间
54 | 金额(USDT)
55 | 收益
56 | 买涨
57 | 买跌
58 | 建设银行
59 | 比特币
60 | 图表
61 | 范围图
62 | 线性图
63 | K线图
64 | 全部余额
65 | 真实账户
66 |
67 | 储蓄卡
68 | 用户名
69 | 实名认证
70 | 出金账户
71 | 目标账户
72 | 金额数量
73 | 交易时间
74 | 总收益
75 | 总百分比
76 | 总投资
77 | 总保证金
78 | 设定
79 | 止盈
80 | 添加止盈
81 | 添加止损
82 | 止损
83 | 默认
84 | 应用
85 | 保证金
86 | 百分比
87 | 订单详情
88 | 保证金以USDT计价,用于承担交易亏损。在平仓后,如盈利保证金全额退还;如亏损还有剩余保证金退还剩余部分;平仓手续费从退还保证金中扣除
89 | 密码登录
90 | 忘记密码
91 | 保存
92 | 新密码
93 | 请输入密码
94 | 请输入编号
95 | 修改成功
96 | 登录成功
97 | 重新获取
98 |
99 | %1$s
100 | %1$s USDT
101 | 订单号 %1$s
102 | 请输入用户名
103 | 请输入姓名
104 | 请输入证件号码
105 | 请输入银行卡号
106 | 立即认证
107 | 认证成功
108 | 关闭
109 | 入金
110 | 出金
111 | 充值数量(USDT)
112 | 请输入充值数量
113 | 阅读相关事项,点击充值需知
114 | 确定
115 | 充值需知
116 | 提币数量(USDT)
117 | 请输入提币数量
118 | DC账户余额
119 | 全部提币
120 | 电子钱包地址
121 | 请输入电子钱包地址
122 | 没有电子钱包,点击注册
123 | - %1$s
124 | + %1$s
125 | 总额(USDT)
126 | 立即添加
127 | 再按一次就可以退出了
128 | 本应用基本功能需要您授予权限
129 | 设定成功
130 | 注册成功
131 | 分
132 | 购买成功
133 | 验证码已发送至
134 | 验证码
135 | 删除
136 | 累计收益(USDT)
137 | 累计投资(USDT)
138 | 账户号码
139 | 货币类型
140 | 储蓄卡片
141 | 当前价格
142 | 当前收益(USDT):
143 | 当前P/L:
144 | 重试
145 | 投资(USDT):
146 | 确认平仓价格
147 | 您确定要退出吗
148 | 取消
149 | 杠杆
150 | 数量
151 | 止损
152 | 成交价格
153 | 平仓价
154 | 成交时间
155 | 结算时间
156 | 订单号
157 | 买入价格
158 | 平仓
159 | 购买
160 | 出售
161 | 指标
162 | 简介
163 | 期权
164 | 热门
165 | 当日
166 | 持仓订单
167 | 历史订单
168 | 暂无订单
169 | 1. 单笔提币按10的倍数执行\n2. 单笔提币金额不低于100USDT\n3. 提币承兑收取手续费为5%比率\n4. 仅支持OMNI协议的电子钱包
170 | 下一步
171 | *为了用户帐号的安全,DCF平台帐号系统将进行全面升级,已完成注册的用户需升级为助记词方式登录,对此给您造成的不便我们深感抱歉。
172 | 原手机号与密码:
173 | 手机号
174 | 新账号与密码
175 | 我知道了,下一步
176 | 使用纸笔正确地抄写助记词。\n手机遗失、损坏、可使用助记词恢复密码。
177 | 请勿将助记词在联网设备储存、传输、不要保存在\n手机相册、邮箱、网盘、社交软件中。\n不要向任何人透漏您的记词。
178 | DCF平台通过12个助记词可找回您的密码,
179 | 知道了
180 | 截屏或分享图片有恶意软件截取助记词的巨大风险。 \n为了您的密码安全,请务必正确抄写助记词。
181 | *DCF平台帐号系统全面升级, 原账号无法登入
182 | 正确抄写下面12个助记词\n助记词是恢复密码的唯一途径
183 | 我已抄好,去验证
184 | 请依次填写助记词(横向输入)
185 | 找回密码
186 | 请输入新密码
187 | 购买USDT
188 | 直充USDT
189 | 请输入电子钱包地址
190 | 账号为字母与数字组合 首位字母 6-18位字符
191 | 密码为6-18位字符
192 | 请输入原手机号
193 | 请输入账号
194 | 请再次输入密码
195 | 请再次输入密码
196 | 两次密码输入不一致
197 | 验证码有误
198 | 无可解约金额
199 | 数 字 资 产 金 融 期 权 交 易
200 | 刷新虚拟账户余额成功
201 | 图片保存成功
202 |
203 |
204 |
--------------------------------------------------------------------------------
/KLineChartLib/src/test/java/com/github/fujianlian/klinechart/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.github.fujianlian.klinechart;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KLineChartView
2 |
3 | Android仿IQ Option K线图实现(包含MA,BOLL,MACD,KDJ,RSI,VOL指标)
4 |
5 | 本项目是在 https://github.com/fujianlian/KLineChart 基础上进行修改的,对UI展示进行了修改。
6 |
7 | 本项目模拟了socket实时推送数据效果,如果项目要使用StompProtocol可以参考我另外一个项目:https://github.com/VincentStory/StompForAndroid ,有具体的接入过程
8 |
9 | ## 效果预览
10 |
11 | ### 效果图中包括范围图,线性图,柱状图随意切换,以及各种指标线展示,自定义显示和隐藏VOL指标
12 |
13 | 
14 | 
15 |
16 | ## 引入项目流程
17 |
18 | ### 1.xml引入KChartView
19 | ```
20 |
24 |
25 |
26 | ```
27 | ### 2.添加数据并刷新view
28 | ```
29 | datas = DataRequest.getALL(MainActivity.this).subList(0, 500);
30 | adapter.addFooterData(datas);
31 | adapter.notifyDataSetChanged();
32 |
33 | if (kLineChartView != null) {
34 | kLineChartView.startAnimation();
35 | kLineChartView.refreshEnd();
36 | kLineChartView.hideChildDraw();
37 | }
38 | ```
39 | ### 3.显示和隐藏指标线
40 |
41 | ```
42 | setChildDraw(Constants.MA);
43 |
44 | setChildDraw(Constants.BOLL);
45 |
46 | setChildDraw(Constants.MACD);
47 |
48 | setChildDraw(Constants.KDJ);
49 |
50 | setChildDraw(Constants.RSI);
51 |
52 | setChildDraw(Constants.VOL);
53 |
54 | setChildDraw(Constants.CLEAR);
55 | ```
56 | ### 4.如有其他特定需求,需在BaseKLineChartView改写代码完成逻辑计算,和绘制特定效果
57 |
58 | -----------------------完成--------------------
59 |
60 | 如果对你有所帮助的话,欢迎Star或者Fork,有遇到其他问题可以加我vx进行沟通
61 | QQ:459005147 备注:android交流
62 |
63 | ```
64 | Copyright 2018 VincentStory
65 |
66 | Licensed under the Apache License, Version 2.0 (the "License");
67 | you may not use this file except in compliance with the License.
68 | You may obtain a copy of the License at
69 |
70 | http://www.apache.org/licenses/LICENSE-2.0
71 |
72 | Unless required by applicable law or agreed to in writing, software
73 | distributed under the License is distributed on an "AS IS" BASIS,
74 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75 | See the License for the specific language governing permissions and
76 | limitations under the License.
77 |
78 | ```
79 |
80 |
81 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.android.compileSdkVersion
5 |
6 | defaultConfig {
7 | applicationId rootProject.ext.android.applicationId
8 | minSdkVersion rootProject.ext.android.minSdkVersion
9 | targetSdkVersion rootProject.ext.android.targetSdkVersion
10 | versionCode rootProject.ext.android.versionCode
11 | versionName rootProject.ext.android.versionName
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | multiDexEnabled true
14 |
15 | ndk {
16 | abiFilters "armeabi", "armeabi-v7a", "x86"
17 | }
18 |
19 |
20 | }
21 | packagingOptions {
22 | doNotStrip '*/mips/*.so'
23 | doNotStrip '*/mips64/*.so'
24 | }
25 |
26 | buildTypes {
27 | release {
28 | minifyEnabled false
29 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
30 | }
31 | }
32 | sourceSets {
33 | main {
34 | java {
35 | srcDir 'src/main/java'
36 | }
37 |
38 | }
39 | }
40 |
41 |
42 |
43 | compileOptions {
44 | //https://www.jianshu.com/p/f2b58ff0b152
45 | //强制使用1.8的jdk 这是让你的IDE强制使用JAVA8
46 | sourceCompatibility rootProject.ext.dependVersion.appSourceCompatibility
47 | targetCompatibility rootProject.ext.dependVersion.appTargetCompatibility
48 | }
49 | }
50 |
51 | dependencies {
52 | implementation fileTree(dir: 'libs', include: ['*.jar'])
53 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
54 | testImplementation 'junit:junit:4.12'
55 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
56 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
57 |
58 | api rootProject.ext.dependencies.design
59 | api rootProject.ext.dependencies.appcompatV7
60 | api rootProject.ext.dependencies.supportV4
61 | implementation project(':KLineChartLib')
62 | implementation 'com.google.code.gson:gson:2.2.4'
63 | implementation 'com.jakewharton:butterknife:8.5.1'
64 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
65 | implementation rootProject.ext.dependencies.baseAdater
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\sdt1\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | #-----------------混淆配置设定------------------------------------------------------------------------
20 | -optimizationpasses 5 #指定代码压缩级别
21 | -dontusemixedcaseclassnames #混淆时不会产生形形色色的类名
22 | -dontskipnonpubliclibraryclasses #指定不忽略非公共类库
23 | -dontpreverify #不预校验,如果需要预校验,是-dontoptimize
24 | -ignorewarnings #屏蔽警告
25 | -verbose #混淆时记录日志
26 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #优化
27 |
28 | -dontoptimize
29 | -dontwarn cn.jpush.**
30 | -keep class cn.jpush.** { *; }
31 |
32 | -dontwarn cn.jiguang.**
33 | -keep class cn.jiguang.** { *; }
34 | -keep public class cn.jiguang.analytics.android.api.** {
35 | *;
36 | }
37 |
38 |
39 | #-----------------不需要混淆第三方类库------------------------------------------------------------------
40 | -dontwarn android.support.v4.** #去掉警告
41 | -keep class android.support.v4.** { *; } #过滤android.support.v4
42 | -keep interface android.support.v4.app.** { *; }
43 | -keep public class * extends android.support.v4.**
44 | -keep public class * extends android.app.Fragment
45 |
46 | -keep class org.apache.**{*;} #过滤commons-httpclient-3.1.jar
47 |
48 | -keep class com.fasterxml.jackson.**{*;} #过滤jackson-core-2.1.4.jar等
49 |
50 | -dontwarn com.lidroid.xutils.** #去掉警告
51 | -keep class com.lidroid.xutils.**{*;} #过滤xUtils-2.6.14.jar
52 | -keep class * extends java.lang.annotation.Annotation{*;} #这是xUtils文档中提到的过滤掉注解
53 | -keep public class * implements com.bumptech.glide.module.GlideModule
54 | -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
55 | **[] $VALUES;
56 | public *;
57 | }
58 | -keep class butterknife.** { *; }
59 | -dontwarn butterknife.internal.**
60 | -keep class **$$ViewBinder { *; }
61 | -keepclasseswithmembernames class * {
62 | @butterknife.* ;
63 | }
64 | -keepclasseswithmembernames class * {
65 | @butterknife.* ;
66 | }
67 | -dontwarn android.support.**
68 | -dontwarn com.google.android.maps.**
69 | -dontwarn com.slidingmenu.lib.app.SlidingMapActivity
70 | -keep class android.support.** { *; }
71 | -keep class com.actionbarsherlock.** { *; }
72 | -keep interface com.actionbarsherlock.** { *; }
73 | -keep class com.slidingmenu.** { *; }
74 | -keep interface com.slidingmenu.** { *; }
75 | -keepclassmembers class * implements java.io.Serializable {
76 | static final long serialVersionUID;
77 | private static final java.io.ObjectStreamField[] serialPersistentFields;
78 | private void writeObject(java.io.ObjectOutputStream);
79 | private void readObject(java.io.ObjectInputStream);
80 | java.lang.Object writeReplace();
81 | java.lang.Object readResolve();
82 | }
83 | -keep public class * implements java.io.Serializable {*;}
84 | -keepclassmembers class * implements android.os.Parcelable {
85 | public ;
86 | private ;
87 | }
88 | -keep class * implements android.os.Parcelable {
89 | public static final android.os.Parcelable$Creator *;
90 | }
91 | -keepclassmembers class fqcn.of.javascript.interface.for.webview {
92 | public *;
93 | }
94 | -keepclassmembers class * extends android.webkit.webViewClient {
95 | public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
96 | public boolean *(android.webkit.WebView, java.lang.String);
97 | }
98 | -keepclassmembers class * extends android.webkit.webViewClient {
99 | public void *(android.webkit.webView, jav.lang.String);
100 | }
101 | -dontwarn javax.**
102 | -dontwarn org.junit.Test
103 |
104 | -dontwarn android.net.**
105 | -keep class android.net.SSLCertificateSocketFactory{*;}
106 |
107 | -dontwarn com.tencent.mm.**
108 | -keep class com.tencent.mm.**{*;}
109 |
110 | -dontwarn com.loopj.android.http.**
111 | -keep class com.loopj.android.http.** { *; }
112 |
113 | ##微博
114 | -keep public class com.sina.weibo.** {*;}
115 | -dontwarn com.sina.weibo.**
116 | -keep public class com.sina.sso.** {*;}
117 | -dontwarn com.sina.sso.**
118 |
119 | ##otto
120 | -keepattributes *Annotation*
121 | -keepclassmembers class ** {
122 | @com.squareup.otto.Subscribe public *;
123 | @com.squareup.otto.Produce public *;
124 | }
125 |
126 | ##拍照
127 | -keep class com.jph.takephoto.** { *; }
128 | -dontwarn com.jph.takephoto.**
129 |
130 | -keep class com.darsh.multipleimageselect.** { *; }
131 | -dontwarn com.darsh.multipleimageselect.**
132 |
133 | -keep class com.soundcloud.android.crop.** { *; }
134 | -dontwarn com.soundcloud.android.crop.**
135 |
136 | -dontwarn com.alipay.**
137 | -keep class com.alipay.** { *;}
138 | -keep class com.alipay.android.app.IAlixPay{*;}
139 | -keep class com.alipay.android.app.IAlixPay$Stub{*;}
140 | -keep class com.alipay.android.app.IRemoteServiceCallback{*;}
141 | -keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
142 | -keep class com.alipay.sdk.app.PayTask{ public *;}
143 | -keep class com.alipay.sdk.app.AuthTask{ public *;}
144 | -keep class com.alipay.sdk.app.H5PayCallback {
145 | ;
146 | ;
147 | }
148 | -keep class com.alipay.android.phone.mrpc.core.** { *; }
149 | -keep class com.alipay.apmobilesecuritysdk.** { *; }
150 | -keep class com.alipay.mobile.framework.service.annotation.** { *; }
151 | -keep class com.alipay.mobilesecuritysdk.face.** { *; }
152 | -keep class com.alipay.tscenter.biz.rpc.** { *; }
153 | -keep class org.json.alipay.** { *; }
154 | -keep class com.alipay.tscenter.** { *; }
155 | -keep class com.ta.utdid2.** { *;}
156 | -keep class com.ut.device.** { *;}
157 |
158 | #okhttputils
159 | -dontwarn com.zhy.http.**
160 | -keep class com.zhy.http.**{*;}
161 | #okhttp
162 | -dontwarn okhttp3.**
163 | -keep class okhttp3.**{*;}
164 | #okio
165 | -dontwarn okio.**
166 | -keep class okio.**{*;}
167 |
168 | -keepattributes Signature
169 | # For using GSON @Expose annotation
170 | -keepattributes *Annotation*
171 | # Gson specific classes
172 | -dontwarn sun.misc.**
173 | -keep class * implements com.google.gson.TypeAdapterFactory
174 | -keep class * implements com.google.gson.JsonSerializer
175 | -keep class * implements com.google.gson.JsonDeserializer
176 |
177 | -dontwarn com.mcxtzhang.nestlistview.**
178 | -keep class com.mcxtzhang.nestlistview.**{*;}
179 |
180 | -dontwarn com.bigkoo.pickerview.**
181 | -keep class com.bigkoo.pickerview.**{*;}
182 |
183 | -dontwarn lecho.lib.hellocharts.**
184 | -keep class lecho.lib.hellocharts.**{*;}
185 |
186 | -dontwarn com.bm.library.**
187 | -keep class com.bm.library.**{*;}
188 |
189 | -dontwarn org.java_websocket.**
190 | -keep class org.java_websocket.**{*;}
191 |
192 | -keep class com.chad.library.adapter.** {
193 | *;
194 | }
195 | -keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter
196 | -keep public class * extends com.chad.library.adapter.base.BaseViewHolder
197 | -keepclassmembers public class * extends com.chad.library.adapter.base.BaseViewHolder {
198 | (android.view.View);
199 | }
200 |
201 | -dontwarn q.rorbin.verticaltablayout.**
202 | -keep class q.rorbin.verticaltablayout.**{*;}
203 |
204 | -dontwarn com.readystatesoftware.systembartint.**
205 | -keep class com.readystatesoftware.systembartint.**{*;}
206 |
207 | -dontwarn com.elbbbird.android.socialsdk.**
208 | -keep class com.elbbbird.android.socialsdk.**{*;}
209 |
210 |
211 |
212 | #-----------------不需要混淆系统组件等-------------------------------------------------------------------
213 | -keep public class * extends android.app.Activity
214 | -keep public class * extends android.app.Application
215 | -keep public class * extends android.app.Service
216 | -keep public class * extends android.content.BroadcastReceiver
217 | -keep public class * extends android.content.ContentProvider
218 | -keep public class * extends android.preference.Preference
219 | -keep public class com.android.vending.licensing.ILicensingService
220 | -keep class **.R$* {
221 | *;-ru
222 | }
223 | -keepclassmembers class * {
224 | void *(**On*Event);
225 | }
226 | -keepattributes EnclosingMethod
227 |
228 | -keep class com.android.aishangauction.model.**{*;} #过滤掉自己编写的实体类
229 |
230 |
231 | #----------------保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在------------------------------------
232 | -keepclasseswithmembernames class * {
233 | public (android.content.Context, android.util.AttributeSet);
234 | }
235 |
236 | -keepclasseswithmembernames class * {
237 | public (android.content.Context, android.util.AttributeSet, int);
238 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vincent/story/DataBean.java:
--------------------------------------------------------------------------------
1 | package com.vincent.story;
2 |
3 | public class DataBean {
4 | private String data;
5 | private boolean isSelected;
6 | private int type;
7 | private int position;
8 |
9 | public int getPosition() {
10 | return position;
11 | }
12 |
13 | public void setPosition(int position) {
14 | this.position = position;
15 | }
16 |
17 | public int getType() {
18 | return type;
19 | }
20 |
21 | public void setType(int type) {
22 | this.type = type;
23 | }
24 |
25 | public boolean isSelected() {
26 | return isSelected;
27 | }
28 |
29 | public void setSelected(boolean selected) {
30 | isSelected = selected;
31 | }
32 |
33 | public String getData() {
34 | return data;
35 | }
36 |
37 | public void setData(String data) {
38 | this.data = data;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "DataBean{" +
44 | "data='" + data + '\'' +
45 | ", isSelected=" + isSelected +
46 | ", type=" + type +
47 | ", position=" + position +
48 | '}';
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vincent/story/DataRequest.java:
--------------------------------------------------------------------------------
1 | package com.vincent.story;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import com.github.fujianlian.klinechart.DataHelper;
7 | import com.github.fujianlian.klinechart.KLineEntity;
8 | import com.google.gson.Gson;
9 | import com.google.gson.reflect.TypeToken;
10 |
11 |
12 | import java.io.InputStream;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * 模拟网络请求
18 | * Created by tifezh on 2017/7/3.
19 | */
20 |
21 | public class DataRequest {
22 | private static List datas = null;
23 |
24 | public static String getStringFromAssert(Context context, String fileName) {
25 | try {
26 | InputStream in = context.getResources().getAssets().open(fileName);
27 | int length = in.available();
28 | byte[] buffer = new byte[length];
29 | in.read(buffer);
30 | return new String(buffer, 0, buffer.length, "UTF-8");
31 | } catch (Exception e) {
32 | e.printStackTrace();
33 | Log.i("exception==",e.getMessage());
34 | }
35 | return "";
36 | }
37 |
38 | public static List getALL(Context context) {
39 | if (datas == null) {
40 | // String string = getStringFromAssert(context, "ibm.json");
41 | // Log.i("string==", string);
42 | final List data = new Gson().fromJson(getStringFromAssert(context, "ibm.json"), new TypeToken>() {
43 | }.getType());
44 |
45 | DataHelper.calculate(data);
46 | datas = data;
47 | }
48 | return datas;
49 | }
50 |
51 | public static List addData(Context context) {
52 | if (datas != null) {
53 | KLineEntity entity = new KLineEntity();
54 | entity.setClose((float) 86.875);
55 | entity.setDate("2016/10/28");
56 | entity.setHigh((float) 154.059998);
57 | entity.setLow((float) 152.020004);
58 | entity.setOpen((float) 152.820007);
59 | entity.setVolume((float) 4126800);
60 | datas.add(new KLineEntity());
61 | DataHelper.calculate(datas);
62 | }
63 | return datas;
64 | }
65 |
66 |
67 | /**
68 | * 分页查询
69 | *
70 | * @param context
71 | * @param offset 开始的索引
72 | * @param size 每次查询的条数
73 | */
74 | public static List getData(Context context, int offset, int size) {
75 | List all = getALL(context);
76 | List data = new ArrayList<>();
77 | int start = Math.max(0, all.size() - 1 - offset - size);
78 | int stop = Math.min(all.size(), all.size() - offset);
79 | for (int i = start; i < stop; i++) {
80 | data.add(all.get(i));
81 | }
82 | return data;
83 | }
84 |
85 | }
86 |
87 |
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vincent/story/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.vincent.story;
2 |
3 |
4 | import android.os.Bundle;
5 | import android.support.annotation.LayoutRes;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.support.v7.widget.GridLayoutManager;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.util.Log;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.view.WindowManager;
14 | import android.widget.TextView;
15 |
16 | import com.github.fujianlian.klinechart.KLineChartAdapter;
17 | import com.github.fujianlian.klinechart.KLineChartView;
18 | import com.github.fujianlian.klinechart.KLineEntity;
19 | import com.github.fujianlian.klinechart.draw.Status;
20 | import com.github.fujianlian.klinechart.utils.Constants;
21 | import com.vincent.story.adapter.DateCycleAdapter;
22 |
23 | import java.util.ArrayList;
24 | import java.util.List;
25 | import java.util.Timer;
26 | import java.util.TimerTask;
27 |
28 | import butterknife.ButterKnife;
29 | import butterknife.OnClick;
30 | import butterknife.Unbinder;
31 |
32 | import static com.github.fujianlian.klinechart.utils.Constants.BOLL;
33 | import static com.github.fujianlian.klinechart.utils.Constants.CANDLE_TYPE;
34 | import static com.github.fujianlian.klinechart.utils.Constants.LINE_TYPE;
35 | import static com.github.fujianlian.klinechart.utils.Constants.RANG_ITEM;
36 | import static com.github.fujianlian.klinechart.utils.Constants.RANG_TYPE;
37 |
38 |
39 | public class MainActivity extends AppCompatActivity {
40 |
41 | private KLineChartView kLineChartView;
42 |
43 | private List datas;//模拟历史数据
44 |
45 | private List newDatas = new ArrayList<>();//模拟最新数据
46 |
47 | protected KLineChartAdapter adapter = new KLineChartAdapter();
48 |
49 | private int position = 6;//默认关闭子view
50 |
51 | private Unbinder mBinder;
52 |
53 | private Timer timer = new Timer();//当前时间刷新
54 |
55 | private int mSecond = 0;//秒数
56 |
57 | @Override
58 | protected void onCreate(@Nullable Bundle savedInstanceState) {
59 | super.onCreate(savedInstanceState);
60 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
61 | setContentView(R.layout.activity_main);
62 | mBinder = ButterKnife.bind(this);
63 | kLineChartView = findViewById(R.id.kLineChartView);
64 |
65 | kLineChartView.setAdapter(adapter);
66 | kLineChartView.justShowLoading();
67 |
68 |
69 | datas = DataRequest.getALL(MainActivity.this).subList(0, 500);
70 | newDatas.addAll(datas);
71 | Log.i("data==", datas.toString());
72 |
73 | adapter.addFooterData(datas);
74 | adapter.notifyDataSetChanged();
75 |
76 | if (kLineChartView != null) {
77 | kLineChartView.startAnimation();
78 | kLineChartView.refreshEnd();
79 | kLineChartView.hideChildDraw();
80 | }
81 |
82 | setChildDraw(Constants.CLEAR);
83 |
84 | refreshData();
85 |
86 |
87 | }
88 |
89 |
90 | @Override
91 | protected void onDestroy() {
92 | super.onDestroy();
93 | mBinder.unbind();
94 | }
95 |
96 | /**
97 | * 每秒刷新一次数据 ,每5秒新增一条数据
98 | */
99 | private void refreshData() {
100 | timer.schedule(new TimerTask() {
101 | @Override
102 | public void run() {
103 | if (mSecond + RANG_ITEM + 1 >= newDatas.size()) {
104 | mSecond = 0;
105 | }
106 | KLineEntity kLineEntity = newDatas.get(newDatas.size() - mSecond - RANG_ITEM - 1);
107 | mSecond++;
108 | if (mSecond % 5 == 0) {
109 | datas.add(datas.size() - RANG_ITEM, kLineEntity);
110 | adapter.addData(kLineEntity, 0, "2");
111 | } else {
112 | adapter.replaceData(kLineEntity, 0, "2");
113 | datas.set(datas.size() - RANG_ITEM - 1, kLineEntity);
114 | }
115 | // adapter.addFooterData(datas);
116 | adapter.notifyDataSetChanged();
117 |
118 | }
119 | }, 1000, 1000);
120 | }
121 |
122 |
123 | /**
124 | * 显示底部k线view和MA BOLL SAR
125 | *
126 | * @param position
127 | */
128 | public void setChildDraw(int position) {
129 | this.position = position;
130 | if (kLineChartView != null) {
131 | if (position == Constants.MA) {
132 | kLineChartView.changeMainDrawType(Status.MA);
133 | } else if (position == Constants.BOLL) {
134 | kLineChartView.changeMainDrawType(Status.BOLL);
135 | } else if (position != Constants.CLEAR) {
136 | position -= 2;
137 | kLineChartView.setChildDraw(position);
138 | } else {
139 | hideChildView();
140 | }
141 |
142 | }
143 | adapter.notifyDataSetChanged();
144 | }
145 |
146 | public void hideChildView() {
147 | if (kLineChartView != null) {
148 | kLineChartView.hideChildDraw();
149 | kLineChartView.changeMainDrawType(Status.NONE);
150 | }
151 | }
152 |
153 | public void setKlineType(String klineType) {
154 | if (kLineChartView != null) {
155 | kLineChartView.setKlineType(klineType);
156 | }
157 | adapter.notifyDataSetChanged();
158 |
159 | }
160 |
161 |
162 | @OnClick({R.id.tv_rang, R.id.tv_line, R.id.tv_candle, R.id.tv_ma, R.id.tv_boll, R.id.tv_macd
163 | , R.id.tv_kdj, R.id.tv_rsi, R.id.tv_vol, R.id.tv_clear})
164 | public void onClick(View v) {
165 | switch (v.getId()) {
166 | case R.id.tv_rang:
167 | setKlineType(RANG_TYPE);
168 | break;
169 | case R.id.tv_line:
170 | setKlineType(LINE_TYPE);
171 | break;
172 | case R.id.tv_candle:
173 | setKlineType(CANDLE_TYPE);
174 | break;
175 | case R.id.tv_ma:
176 | setChildDraw(Constants.MA);
177 | break;
178 | case R.id.tv_boll:
179 | setChildDraw(Constants.BOLL);
180 | break;
181 | case R.id.tv_macd:
182 | setChildDraw(Constants.MACD);
183 | break;
184 | case R.id.tv_kdj:
185 | setChildDraw(Constants.KDJ);
186 | break;
187 | case R.id.tv_rsi:
188 | setChildDraw(Constants.RSI);
189 | break;
190 | case R.id.tv_vol:
191 | setChildDraw(Constants.VOL);
192 | break;
193 | case R.id.tv_clear:
194 | setChildDraw(Constants.CLEAR);
195 | break;
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vincent/story/adapter/DateCycleAdapter.java:
--------------------------------------------------------------------------------
1 | package com.vincent.story.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.content.ContextCompat;
6 | import android.widget.TextView;
7 |
8 |
9 | import com.chad.library.adapter.base.BaseQuickAdapter;
10 | import com.chad.library.adapter.base.BaseViewHolder;
11 | import com.vincent.story.DataBean;
12 | import com.vincent.story.R;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * 时间周期适配器
18 | */
19 | public class DateCycleAdapter extends BaseQuickAdapter {
20 |
21 | private DateListener listener;
22 |
23 |
24 | public void setListener(DateListener listener) {
25 | this.listener = listener;
26 | }
27 |
28 | public DateCycleAdapter(Context context, int layoutResId, @Nullable List data) {
29 | super(layoutResId, data);
30 | this.mContext = context;
31 | }
32 |
33 | @Override
34 | protected void convert(BaseViewHolder helper, DataBean item) {
35 | helper.setText(R.id.tv_data, item.getData());
36 | if (item.isSelected())
37 | ((TextView) helper.getView(R.id.tv_data)).setTextColor(ContextCompat.getColor(mContext, R.color.color_6384FF));
38 | else
39 | ((TextView) helper.getView(R.id.tv_data)).setTextColor(ContextCompat.getColor(mContext, R.color.white));
40 |
41 | helper.getView(R.id.tv_data).setOnClickListener(l -> {
42 | // initData();
43 | listener.chooseDate(item.getData(), item.getPosition());
44 | });
45 |
46 | }
47 |
48 | //
49 | // public void initData() {
50 | //// List list = getData();
51 | // for (DataBean bean : getData()) {
52 | // bean.setSelected(false);
53 | // }
54 | // }
55 |
56 | public interface DateListener {
57 | void chooseDate(String period, int position);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vincent/story/app/ActivityStack.java:
--------------------------------------------------------------------------------
1 | package com.vincent.story.app;
2 |
3 | import android.app.Activity;
4 |
5 | import java.util.LinkedList;
6 |
7 | public class ActivityStack {
8 | /**
9 | * 存activity的list,方便管理activity
10 | */
11 | public LinkedList activityList = null;
12 |
13 | public ActivityStack() {
14 | activityList = new LinkedList();
15 | }
16 |
17 | /**
18 | * 将Activity添加到activityList中
19 | *
20 | * @param activity
21 | */
22 | public void addActivity(Activity activity) {
23 | activityList.add(activity);
24 | }
25 |
26 | /**
27 | * 获取栈顶Activity
28 | *
29 | * @return
30 | */
31 | public Activity getLastActivity() {
32 | return activityList.getLast();
33 | }
34 |
35 | /**
36 | * 将Activity移除
37 | *
38 | * @param activity
39 | */
40 | public void removeActivity(Activity activity) {
41 | if (null != activity && activityList.contains(activity)) {
42 | activityList.remove(activity);
43 | }
44 | }
45 |
46 | /**
47 | * 判断某一Activity是否在运行
48 | *
49 | * @param className
50 | * @return
51 | */
52 | public boolean isActivityRunning(String className) {
53 | if (className != null) {
54 | for (Activity activity : activityList) {
55 | if (activity.getClass().getName().equals(className)) {
56 | return true;
57 | }
58 | }
59 | }
60 | return false;
61 | }
62 |
63 |
64 | /**
65 | * 退出所有的Activity
66 | */
67 | public void finishAllActivity() {
68 | for (Activity activity : activityList) {
69 | if (null != activity) {
70 | activity.finish();
71 | }
72 | }
73 | }
74 |
75 | /**
76 | * 退出应用程序
77 | */
78 | public void AppExit() {
79 | try {
80 | finishAllActivity();
81 | // 杀死该应用进程
82 | android.os.Process.killProcess(android.os.Process.myPid());
83 | System.exit(0);
84 | } catch (Exception e) {
85 |
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vincent/story/app/MyApp.java:
--------------------------------------------------------------------------------
1 | package com.vincent.story.app;
2 |
3 |
4 | import android.app.Application;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.util.DisplayMetrics;
8 |
9 |
10 | public class MyApp extends Application {
11 |
12 | public static MyApp instance;
13 | //临时保存 需要登录才能访问的页面 在登录成功后跳转
14 | private Intent intent;
15 | //屏幕宽高
16 | int screenWidth;
17 | int screenHeight;
18 | /**
19 | * Activity 栈
20 | */
21 | public ActivityStack mActivityStack = null;
22 |
23 | @Override
24 | public void onCreate() {
25 | super.onCreate();
26 | instance = this;
27 | //1、通过WindowManager获取
28 | DisplayMetrics dm = new DisplayMetrics();
29 | screenWidth = dm.heightPixels; // 屏幕宽(像素,如:480px)
30 | screenHeight = dm.widthPixels; // 屏幕高(像素)
31 | //初始化友盟推送 不用友盟换极光
32 | //UmengHelper.getInstance().initUmeng();
33 | // JPushInterface.setDebugMode(true);
34 |
35 | mActivityStack = new ActivityStack();
36 |
37 |
38 | // String registrationId = JPushInterface.getRegistrationID(this);
39 | // SharedPreferencesUtil.put(getApplicationContext(), "RegistrationId", registrationId);
40 | // L.i("RegistrationId", registrationId);
41 | }
42 |
43 |
44 | public int getScreenWidth() {
45 | return screenWidth;
46 | }
47 |
48 | public int getScreenHeight() {
49 | return screenHeight;
50 | }
51 |
52 | public static MyApp getInstance() {
53 | return instance;
54 | }
55 |
56 | public Intent getIntent() {
57 | return intent;
58 | }
59 |
60 | public void putIntent(Intent intent) {
61 | this.intent = intent;
62 | }
63 |
64 | public void jumpToTargetActivity(Context context) {
65 | context.startActivity(intent);
66 | this.intent = null;
67 | }
68 |
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
34 |
35 |
36 |
43 |
44 |
51 |
52 |
53 |
60 |
61 |
68 |
69 |
76 |
77 |
84 |
85 |
92 |
93 |
100 |
101 |
108 |
109 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_tv_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/app/src/main/res/mipmap-xhdpi/ic_no_image.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_temp_load.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/app/src/main/res/mipmap-xhdpi/icon_temp_load.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-sw384dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 17.0667dp
4 | 17.0667dp
5 | 53.3333dp
6 | @dimen/dp_15
7 | -64.0000dp
8 | -32.0000dp
9 | -21.3333dp
10 | -12.8000dp
11 | -10.6667dp
12 | -8.5333dp
13 | -5.3333dp
14 | -2.1333dp
15 | -1.0667dp
16 | 0.0000dp
17 | 0.1067dp
18 | 0.5333dp
19 | 1.0667dp
20 | 1.6000dp
21 | 2.1333dp
22 | 2.6667dp
23 | 3.2000dp
24 | 3.7333dp
25 | 4.2667dp
26 | 4.8000dp
27 | 5.3333dp
28 | 6.4000dp
29 | 7.4667dp
30 | 8.0000dp
31 | 8.5333dp
32 | 9.6000dp
33 | 10.6667dp
34 | 11.7333dp
35 | 12.8000dp
36 | 13.8667dp
37 | 14.9333dp
38 | 16.0000dp
39 | 17.0667dp
40 | 18.1333dp
41 | 19.2000dp
42 | 20.2667dp
43 | 21.3333dp
44 | 22.4000dp
45 | 23.4667dp
46 | 24.5333dp
47 | 25.6000dp
48 | 26.6667dp
49 | 27.7333dp
50 | 28.8000dp
51 | 29.8667dp
52 | 30.9333dp
53 | 32.0000dp
54 | 33.0667dp
55 | 34.1333dp
56 | 35.2000dp
57 | 36.2667dp
58 | 37.3333dp
59 | 38.4000dp
60 | 39.4667dp
61 | 40.5333dp
62 | 41.6000dp
63 | 42.6667dp
64 | 43.7333dp
65 | 44.8000dp
66 | 45.8667dp
67 | 46.9333dp
68 | 48.0000dp
69 | 49.0667dp
70 | 50.1333dp
71 | 51.2000dp
72 | 52.2667dp
73 | 53.3333dp
74 | 54.4000dp
75 | 55.4667dp
76 | 56.5333dp
77 | 57.6000dp
78 | 58.6667dp
79 | 59.7333dp
80 | 60.8000dp
81 | 61.8667dp
82 | 62.9333dp
83 | 64.0000dp
84 | 65.0667dp
85 | 66.1333dp
86 | 67.2000dp
87 | 68.2667dp
88 | 69.3333dp
89 | 70.4000dp
90 | 71.4667dp
91 | 72.5333dp
92 | 73.6000dp
93 | 74.6667dp
94 | 75.7333dp
95 | 76.8000dp
96 | 77.8667dp
97 | 78.9333dp
98 | 80.0000dp
99 | 81.0667dp
100 | 82.1333dp
101 | 83.2000dp
102 | 84.2667dp
103 | 85.3333dp
104 | 86.4000dp
105 | 87.4667dp
106 | 88.5333dp
107 | 89.6000dp
108 | 90.6667dp
109 | 91.7333dp
110 | 92.8000dp
111 | 93.8667dp
112 | 94.9333dp
113 | 96.0000dp
114 | 97.0667dp
115 | 98.1333dp
116 | 99.2000dp
117 | 100.2667dp
118 | 101.3333dp
119 | 102.4000dp
120 | 103.4667dp
121 | 104.5333dp
122 | 105.6000dp
123 | 106.6667dp
124 | 107.7333dp
125 | 108.8000dp
126 | 109.8667dp
127 | 110.9333dp
128 | 111.4667dp
129 | 112.0000dp
130 | 113.0667dp
131 | 114.1333dp
132 | 115.2000dp
133 | 116.2667dp
134 | 117.3333dp
135 | 118.4000dp
136 | 119.4667dp
137 | 120.5333dp
138 | 121.6000dp
139 | 122.6667dp
140 | 123.7333dp
141 | 124.8000dp
142 | 125.8667dp
143 | 126.9333dp
144 | 128.0000dp
145 | 129.0667dp
146 | 130.1333dp
147 | 131.2000dp
148 | 132.2667dp
149 | 133.3333dp
150 | 134.4000dp
151 | 135.4667dp
152 | 136.5333dp
153 | 137.6000dp
154 | 138.6667dp
155 | 139.7333dp
156 | 140.8000dp
157 | 141.8667dp
158 | 142.9333dp
159 | 143.4667dp
160 | 144.0000dp
161 | 145.0667dp
162 | 146.1333dp
163 | 147.2000dp
164 | 148.2667dp
165 | 149.3333dp
166 | 150.4000dp
167 | 151.4667dp
168 | 152.5333dp
169 | 153.6000dp
170 | 154.6667dp
171 | 155.7333dp
172 | 156.8000dp
173 | 157.8667dp
174 | 158.9333dp
175 | 160.0000dp
176 | 161.0667dp
177 | 162.1333dp
178 | 163.2000dp
179 | 164.2667dp
180 | 165.3333dp
181 | 166.4000dp
182 | 167.4667dp
183 | 168.5333dp
184 | 169.6000dp
185 | 170.6667dp
186 | 171.7333dp
187 | 172.8000dp
188 | 173.8667dp
189 | 174.9333dp
190 | 176.0000dp
191 | 177.0667dp
192 | 178.1333dp
193 | 179.2000dp
194 | 180.2667dp
195 | 181.3333dp
196 | 182.4000dp
197 | 183.4667dp
198 | 184.5333dp
199 | 185.6000dp
200 | 186.6667dp
201 | 187.7333dp
202 | 188.8000dp
203 | 189.8667dp
204 | 190.9333dp
205 | 192.0000dp
206 | 193.0667dp
207 | 194.1333dp
208 | 195.2000dp
209 | 196.2667dp
210 | 197.3333dp
211 | 198.4000dp
212 | 199.4667dp
213 | 200.5333dp
214 | 201.6000dp
215 | 202.6667dp
216 | 203.7333dp
217 | 204.0000dp
218 | 204.8000dp
219 | 205.8667dp
220 | 206.9333dp
221 | 208.0000dp
222 | 209.0667dp
223 | 210.1333dp
224 | 211.2000dp
225 | 212.2667dp
226 | 213.3333dp
227 | 214.4000dp
228 | 215.4667dp
229 | 216.5333dp
230 | 217.6000dp
231 | 218.6667dp
232 | 219.7333dp
233 | 220.8000dp
234 | 221.8667dp
235 | 222.9333dp
236 | 224.0000dp
237 | 225.0667dp
238 | 226.1333dp
239 | 227.2000dp
240 | 228.2667dp
241 | 229.3333dp
242 | 230.4000dp
243 | 231.4667dp
244 | 232.5333dp
245 | 233.6000dp
246 | 234.6667dp
247 | 235.7333dp
248 | 236.8000dp
249 | 237.8667dp
250 | 238.9333dp
251 | 240.0000dp
252 | 241.0667dp
253 | 242.1333dp
254 | 243.2000dp
255 | 244.2667dp
256 | 245.3333dp
257 | 246.4000dp
258 | 247.4667dp
259 | 248.5333dp
260 | 249.6000dp
261 | 250.6667dp
262 | 251.7333dp
263 | 252.8000dp
264 | 253.8667dp
265 | 254.9333dp
266 | 256.0000dp
267 | 257.0667dp
268 | 258.1333dp
269 | 259.2000dp
270 | 260.2667dp
271 | 261.3333dp
272 | 262.4000dp
273 | 263.4667dp
274 | 264.5333dp
275 | 265.6000dp
276 | 266.6667dp
277 | 267.7333dp
278 | 268.8000dp
279 | 269.8667dp
280 | 270.9333dp
281 | 272.0000dp
282 | 273.0667dp
283 | 274.1333dp
284 | 275.2000dp
285 | 276.2667dp
286 | 277.3333dp
287 | 278.4000dp
288 | 279.4667dp
289 | 280.5333dp
290 | 281.6000dp
291 | 282.6667dp
292 | 283.7333dp
293 | 284.8000dp
294 | 285.8667dp
295 | 286.9333dp
296 | 288.0000dp
297 | 289.0667dp
298 | 290.1333dp
299 | 291.2000dp
300 | 292.2667dp
301 | 293.3333dp
302 | 294.4000dp
303 | 295.4667dp
304 | 296.5333dp
305 | 297.6000dp
306 | 298.6667dp
307 | 299.7333dp
308 | 300.8000dp
309 | 301.8667dp
310 | 302.9333dp
311 | 304.0000dp
312 | 305.0667dp
313 | 306.1333dp
314 | 307.2000dp
315 | 308.2667dp
316 | 309.3333dp
317 | 310.4000dp
318 | 311.4667dp
319 | 312.5333dp
320 | 313.6000dp
321 | 314.6667dp
322 | 315.7333dp
323 | 316.8000dp
324 | 317.8667dp
325 | 318.9333dp
326 | 320.0000dp
327 | 321.0667dp
328 | 322.1333dp
329 | 323.2000dp
330 | 324.2667dp
331 | 325.3333dp
332 | 326.4000dp
333 | 327.4667dp
334 | 328.5333dp
335 | 329.6000dp
336 | 330.6667dp
337 | 331.7333dp
338 | 332.8000dp
339 | 333.8667dp
340 | 334.9333dp
341 | 336.0000dp
342 | 337.0667dp
343 | 338.1333dp
344 | 339.2000dp
345 | 340.2667dp
346 | 341.3333dp
347 | 342.4000dp
348 | 343.4667dp
349 | 344.5333dp
350 | 345.6000dp
351 | 346.6667dp
352 | 347.7333dp
353 | 348.8000dp
354 | 349.8667dp
355 | 350.9333dp
356 | 352.0000dp
357 | 353.0667dp
358 | 354.1333dp
359 | 355.2000dp
360 | 356.2667dp
361 | 357.3333dp
362 | 358.4000dp
363 | 359.4667dp
364 | 360.5333dp
365 | 361.6000dp
366 | 362.6667dp
367 | 363.7333dp
368 | 364.8000dp
369 | 365.8667dp
370 | 366.9333dp
371 | 368.0000dp
372 | 369.0667dp
373 | 370.1333dp
374 | 371.2000dp
375 | 372.2667dp
376 | 373.3333dp
377 | 374.4000dp
378 | 375.4667dp
379 | 376.5333dp
380 | 377.6000dp
381 | 378.6667dp
382 | 379.7333dp
383 | 380.8000dp
384 | 381.8667dp
385 | 382.9333dp
386 | 384.0000dp
387 | 389.3333dp
388 | 394.6667dp
389 | 426.6667dp
390 | 437.3333dp
391 | 450.1333dp
392 | 503.4667dp
393 | 533.3333dp
394 | 640.0000dp
395 | 682.6667dp
396 | 768.0000dp
397 | 6.4000sp
398 | 7.4667sp
399 | 8.5333sp
400 | 9.6000sp
401 | 10.6667sp
402 | 11.7333sp
403 | 12.8000sp
404 | 13.8667sp
405 | 14.9333sp
406 | 16.0000sp
407 | 17.0667sp
408 | 18.1333sp
409 | 19.2000sp
410 | 20.2667sp
411 | 21.3333sp
412 | 22.4000sp
413 | 23.4667sp
414 | 24.5333sp
415 | 25.6000sp
416 | 26.6667sp
417 | 29.8667sp
418 | 32.0000sp
419 | 34.1333sp
420 | 36.2667sp
421 | 38.4000sp
422 | 40.5333sp
423 | 42.6667sp
424 | 44.8000sp
425 | 51.2000sp
426 |
427 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #1F1F27
5 | #FFFAE0
6 | #707070
7 | #E87439
8 | #F2B89B
9 | #DCB476
10 | #696969
11 |
12 | #FF2741
13 | #FF2741
14 | #FF2741
15 | #FF4081
16 |
17 | #00000000
18 | #55000000
19 | #333333
20 | #292836
21 | #ffffff
22 | #2d2e3d
23 | #292836
24 | #9A9A9A
25 | #D6D6D6
26 | #FFFFFF
27 | #33355C
28 | #3D3E63
29 | #C3C4EA
30 | #67688E
31 | #99FFFFFF
32 | #44FFFFFF
33 | #2E3546
34 | #D04B63
35 | #77E53737
36 |
37 | #4EC2E3
38 |
39 | #2982D1
40 | #232544
41 | #252647
42 | #26284A
43 | #77E0F7
44 | #5577E0F7
45 | #999999
46 | #e5e5e5
47 | #7577AD
48 | #76EE00
49 |
50 | #F5F5F5
51 | #1A202E
52 | #1C1D3A
53 | #5a5a5a
54 | #eeeeee
55 | #333333
56 | #e9ecf0
57 | #cc3A3949
58 | #393a49
59 | #cccccc
60 | #aaaaaa
61 | #808080
62 | #ababab
63 | #ffc000
64 | #FFF000
65 | #FEFEC2
66 | #55797AAF
67 |
68 | #29A8D1
69 | #5529A8D1
70 | #767CA1
71 | #20223F
72 | #34365B
73 | #E6C57D
74 | #ff86b9b5
75 | #80000000
76 | #50000000
77 | #00ffffff
78 | #292836
79 |
80 |
81 | #9e9e9e
82 | #1b66c7
83 |
84 |
85 |
86 | #808080
87 | #ff0000
88 | #d7160f
89 | #FF2741
90 | #FFC024
91 | #CED9E7
92 | #53B4A9
93 | #26284A
94 | #aa1A202E
95 | #7723C224
96 | #346fc3
97 | #ABAABF
98 | #EDEDF3
99 | #2B2D52
100 | #2E3052
101 |
102 |
103 |
104 | #DA8AE5
105 | #39B0E8
106 | #FFC76D
107 | #E7A520
108 | #ffffff
109 |
110 | #202326
111 | #B1B2B6
112 | #c830343C
113 | #30343C
114 | #FF6601
115 |
116 |
117 | #4262DC
118 | #7390FF
119 | #6384FF
120 | #53B4A9
121 | #D04B63
122 | #1F202E
123 | #2E3546
124 | #1A202E
125 | #101625
126 | #656F82
127 | #9D9EC3
128 | #72739C
129 | #393A6B
130 | #797AAF
131 | #0E121C
132 | #5A83FF
133 | #13141E
134 | #1EE39D
135 | #661EE39D
136 | #12A2CA
137 | #6612A2CA
138 | #FF8A7C
139 | #66FF8A7C
140 | #66DE3957
141 | #DE3957
142 | #111622
143 | #2D3445
144 | #30384C
145 | #E64D60
146 | #14ADC2
147 | #6D778B
148 | #E4475D
149 | #CBCFF1
150 | #14B014
151 | #6B778D
152 | #47526D
153 |
154 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | KlineChartView
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
17 |
18 |
22 |
23 |
24 |
29 |
30 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/filepaths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | apply from: "config.gradle"
3 | buildscript {
4 |
5 | repositories {
6 | jcenter()
7 | mavenCentral()
8 | google()
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.2.0'
12 | // classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
14 | // classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
15 | // classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
16 | //GreenDao3依赖
17 | classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
18 | classpath 'com.android.tools.build:gradle:3.0.1'
19 | // NOTE: Do not place your application dependencies here; they belong
20 | // in the individual module build.gradle files
21 | }
22 | }
23 |
24 | allprojects {
25 | repositories {
26 | google()
27 | jcenter()
28 | maven { url "https://jitpack.io" }
29 | }
30 | }
31 |
32 |
33 | task clean(type: Delete) {
34 | delete rootProject.buildDir
35 | }
36 |
--------------------------------------------------------------------------------
/config.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 | plugins = [
3 | library : 'com.android.library',
4 | application: 'com.android.application',
5 | maven : 'com.github.dcendents.android-maven',
6 | bintray : 'com.jfrog.bintray'
7 | ]
8 |
9 | android = [
10 | applicationId : "com.android.project",
11 | compileSdkVersion : 28,
12 | buildToolsVersion : "27.0.3",
13 |
14 | minSdkVersion : 17,
15 | targetSdkVersion : 28,
16 |
17 | versionCode : 1,
18 | versionName : "1.0",
19 | androidSupportVersion: '27.1.1',
20 | junitVersion : "4.12"
21 | ]
22 |
23 | dependVersion = [
24 | support : "28.0.0",
25 | sdkSourceCompatibility: 1.8,
26 | sdkTargetCompatibility: 1.8,
27 | appSourceCompatibility: 1.8,
28 | appTargetCompatibility: 1.8
29 | ]
30 | dependencies = [
31 | // support
32 | supportV4 : "com.android.support:support-v4:${dependVersion.support}",
33 | appcompatV7 : "com.android.support:appcompat-v7:${dependVersion.support}",
34 | recyclerview : "com.android.support:recyclerview-v7:${dependVersion.support}",
35 | design : "com.android.support:design:${dependVersion.support}",
36 | cardView : "com.android.support:cardview-v7:${dependVersion.support}",
37 |
38 | constraintLayout : 'com.android.support.constraint:constraint-layout:1.0.2',
39 |
40 | loading : 'com.yanzhenjie:loading:1.0.2',
41 | swipeRecyclerView : 'com.yanzhenjie:recyclerview-swipe:1.1.3',
42 | //权限管理
43 | easypermissions : 'pub.devrel:easypermissions:0.2.0',
44 | //沉浸式状态栏
45 | statusbaruitl : 'com.jaeger.statusbaruitl:library:1.3.5',
46 | //图片放大缩小框架
47 | photoview : 'com.github.chrisbanes.photoview:library:1.2.3',
48 | //类似微信的图片选择PhotoPicker
49 | //compile 'me.iwf.photopicker:PhotoPicker:0.9.5@aar'
50 | photoPicker : 'me.iwf.photopicker:PhotoPicker:0.1.8',
51 | //PhotoPicker需要用到
52 | nineoldandroids : 'com.nineoldandroids:library:2.4.0',
53 | //PhotoPicker需要用到 glide图片加载框架
54 | glide : 'com.github.bumptech.glide:glide:4.2.0',
55 | //图片压缩
56 | compressHelper : 'com.github.nanchen2251:CompressHelper:1.0.5',
57 | //greendao数据库依赖
58 | greendao : 'org.greenrobot:greendao:3.2.0',
59 | //retrofit
60 | retrofit : 'com.squareup.retrofit2:retrofit:2.2.0',
61 | converterGson : 'com.squareup.retrofit2:converter-gson:2.2.0',
62 | //rx+retrofit
63 | adapterRxjava : 'com.squareup.retrofit2:adapter-rxjava2:2.2.0',
64 | //rxjava
65 | rxjava : 'io.reactivex.rxjava2:rxjava:2.0.8',
66 | rxandroid : 'io.reactivex.rxjava2:rxandroid:2.0.1',
67 | //效果好看的刷新加载库
68 | SmartRefreshLayout : 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.4',
69 | //没有使用特殊Header,可以不加这行
70 | SmartRefreshHeader : 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.4',
71 | //一个开源gif控件
72 | gifDrawable : 'pl.droidsonroids.gif:android-gif-drawable:1.2.3',
73 | //头部广告轮播https://github.com/youth5201314/banner
74 | youthBanner : 'com.youth.banner:banner:1.4.10',
75 | //星星评分控件https://www.cnblogs.com/everhad/p/6828627.html?utm_source=tuicool&utm_medium=referral
76 | ratingStar : 'com.github.everhad:AndroidRatingStar:v1.0.1',
77 | //tag
78 | tagView : 'co.lujun:androidtagview:1.1.4',
79 | //baseAdater
80 | baseAdater : 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30',
81 | //okhttop 日志拦截打印
82 | okhttpInterceptor : 'com.squareup.okhttp3:logging-interceptor:3.4.1',
83 | //弹框
84 | easyPopup : 'com.github.zyyoona7:EasyPopup:1.1.2',
85 | //文本多级联动 地址选择器
86 | TextPickerView : 'com.contrarywind:Android-PickerView:4.1.5',
87 | //EvenBus
88 | EvenBus : 'org.greenrobot:eventbus:3.1.1',
89 | //butterknife
90 | butterknife : 'com.jakewharton:butterknife:8.5.1',
91 | butterknifeCompiler: 'com.jakewharton:butterknife-compiler:8.5.1',
92 |
93 | ]
94 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/img1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/img1.jpg
--------------------------------------------------------------------------------
/img2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VincentStory/KLineChartView/3c6ddc7d735d0cac90eaeb1b692212c9214d284a/img2.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':KLineChartLib'
2 |
--------------------------------------------------------------------------------