├── .gitignore
├── .idea
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── yxy
│ │ └── videolineview
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── demo.gif
│ ├── java
│ │ └── yxy
│ │ │ └── videolineview
│ │ │ ├── ConvertUtils.java
│ │ │ ├── DateUtils.java
│ │ │ ├── MainActivity.java
│ │ │ ├── VideoInfo.java
│ │ │ ├── VideoLineView.java
│ │ │ └── VideoLineViewChangeListener.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── attr.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── yxy
│ └── videolineview
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.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 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VideoLineView
2 | ## android 视频轴 仿海康android端视频轴 、时间轴
3 | ## 可自定义 线条颜色、背景颜色、文字颜色
4 |
5 | # 演示
6 | 
7 |
8 | # qq 1249492252
9 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | defaultConfig {
6 | applicationId "yxy.videolineview"
7 | minSdkVersion 21
8 | targetSdkVersion 26
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:26.1.0'
24 | implementation 'com.android.support.constraint:constraint-layout:1.1.2'
25 | testImplementation 'junit:junit:4.12'
26 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
28 | }
29 |
--------------------------------------------------------------------------------
/app/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 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/yxy/videolineview/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
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() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("yxy.videolineview", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/assets/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/assets/demo.gif
--------------------------------------------------------------------------------
/app/src/main/java/yxy/videolineview/ConvertUtils.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Created by yang on 2018-07-05.
7 | */
8 |
9 | public class ConvertUtils {
10 | public static int dp2px(Context context, float dpValue){
11 | float scale=context.getResources().getDisplayMetrics().density;
12 | return (int)(dpValue*scale+0.5f);
13 | }
14 |
15 | /**
16 | * px转换成dp
17 | */
18 | public static int px2dp(Context context, float pxValue){
19 | float scale=context.getResources().getDisplayMetrics().density;
20 | return (int)(pxValue/scale+0.5f);
21 | }
22 | /**
23 | * sp转换成px
24 | */
25 | public static int sp2px(Context context, float spValue){
26 | float fontScale=context.getResources().getDisplayMetrics().scaledDensity;
27 | return (int) (spValue*fontScale+0.5f);
28 | }
29 | /**
30 | * px转换成sp
31 | */
32 | public static int px2sp(Context context, float pxValue){
33 | float fontScale=context.getResources().getDisplayMetrics().scaledDensity;
34 | return (int) (pxValue/fontScale+0.5f);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/yxy/videolineview/DateUtils.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
2 |
3 | import java.math.BigDecimal;
4 | import java.sql.Timestamp;
5 | import java.text.ParseException;
6 | import java.text.SimpleDateFormat;
7 | import java.util.Calendar;
8 | import java.util.Date;
9 | import java.util.regex.Pattern;
10 |
11 | /**
12 | * 描述:日期工具类
13 | * by minghui yxy
14 | * @date 2013-03-01
15 | */
16 | public class DateUtils {
17 | public static final String DEFAULT_FORMAT_DATE_WITHOUT_TIME = "yyyy-MM-dd";
18 | public static final String DEFAULT_FORMAT_DATE = "yyyy-MM-dd HH:mm:ss";
19 | public static final BigDecimal BASETIME = new BigDecimal("60.00");
20 | public static final Pattern DATE_PATTERN = Pattern.compile("^(?:(?!0000)[0-9]{4}([-/.]?)(?:(?:0?[1-9]|1[0-2])([-/.]?)(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])([-/.]?)(?:29|30)|(?:0?[13578]|1[02])([-/.]?)31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2([-/.]?)29)$");
21 |
22 | public static boolean validateDateFormat(String dateText){
23 | return DATE_PATTERN.matcher(dateText).matches();
24 | }
25 |
26 | public static Timestamp now(){
27 | return new Timestamp(System.currentTimeMillis());
28 | }
29 |
30 | public static Date resetTime(Date date) {
31 | Calendar c = Calendar.getInstance();
32 | c.setTime(date);
33 | c.set(Calendar.HOUR_OF_DAY, 0);
34 | c.set(Calendar.MINUTE, 0);
35 | c.set(Calendar.SECOND, 0);
36 | c.set(Calendar.MILLISECOND, 0);
37 | return c.getTime();
38 | }
39 |
40 | public static String formatDate(Date date, String formatStr) {
41 | return (new SimpleDateFormat((formatStr == null ? DEFAULT_FORMAT_DATE
42 | : formatStr))).format(date);
43 | }
44 |
45 | public static Date formatDate(String dateStr, String formatStr)
46 | throws ParseException {
47 | return (new SimpleDateFormat((formatStr == null ? DEFAULT_FORMAT_DATE
48 | : formatStr))).parse(dateStr);
49 | }
50 |
51 | public static Timestamp formatTime(String dateStr) {
52 | return Timestamp.valueOf(dateStr);
53 | }
54 |
55 | public static int getYear(Date date) {
56 | Calendar c = Calendar.getInstance();
57 | c.setTime(date);
58 | return c.get(Calendar.YEAR);
59 | }
60 |
61 | public static int getYear(String dateStr, String format)
62 | throws ParseException {
63 | return getYear(formatDate(dateStr, format));
64 | }
65 |
66 | public static int getMonth(Date date) {
67 | Calendar c = Calendar.getInstance();
68 | c.setTime(date);
69 | return c.get(Calendar.MONTH) + 1;
70 | }
71 |
72 | public static int getMonth(String dateStr, String format)
73 | throws ParseException {
74 | return getMonth(formatDate(dateStr, format));
75 | }
76 |
77 | public static int getDay(Date date) {
78 | Calendar c = Calendar.getInstance();
79 | c.setTime(date);
80 | return c.get(Calendar.DAY_OF_MONTH);
81 | }
82 |
83 | public static int getDay(String dateStr, String format)
84 | throws ParseException {
85 | return getDay(formatDate(dateStr, format));
86 | }
87 |
88 | public static int getWeekDay(Date date) {
89 | Calendar c = Calendar.getInstance();
90 | c.setTime(date);
91 | return c.get(Calendar.DAY_OF_WEEK);
92 | }
93 |
94 | public static int getWeekDay(String dateStr, String format)
95 | throws ParseException {
96 | return getWeekDay(formatDate(dateStr, format));
97 | }
98 |
99 | public static int getDayCountInMonth(int month, boolean isLeapYear) {
100 | int dayCount = 0;
101 | if (month >= Calendar.JANUARY && month <= Calendar.DECEMBER) {
102 | if (month == Calendar.JANUARY || month == Calendar.MARCH
103 | || month == Calendar.MAY || month == Calendar.JULY
104 | || month == Calendar.AUGUST || month == Calendar.OCTOBER
105 | || month == Calendar.DECEMBER) {
106 | dayCount = 31;
107 | } else if (month == Calendar.APRIL || month == Calendar.JUNE
108 | || month == Calendar.SEPTEMBER
109 | || month == Calendar.NOVEMBER) {
110 | dayCount = 30;
111 | } else if (month == Calendar.FEBRUARY) {
112 | if (isLeapYear) {
113 | dayCount = 29;
114 | } else {
115 | dayCount = 28;
116 | }
117 | }
118 | }
119 | return dayCount;
120 | }
121 |
122 | public static boolean isLeapYear(int year) {
123 | if (year % 4 == 0 || year % 100 != 0 && year % 400 == 0) {
124 | return true;
125 | } else {
126 | return false;
127 | }
128 | }
129 |
130 | public static boolean compareDay(Date d1, Date d2) {
131 | return resetTime(d1).after(resetTime(d2));
132 | }
133 |
134 | /**
135 | * 日期差 modify by jian_xie 2011-12-1
136 | *
137 | * @param startDate
138 | * @param endDate
139 | * @return
140 | */
141 | public static long daySub(Date startDate, Date endDate) {
142 | return (startDate.getTime() - endDate.getTime()) > 0 ? (startDate
143 | .getTime() - endDate.getTime()) / 86400000
144 | : (endDate.getTime() - startDate.getTime()) / 86400000;
145 | }
146 |
147 | public static Date addOneDay(Date date) {
148 | Calendar c = Calendar.getInstance();
149 | c.setTime(date);
150 | c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) + 1);
151 | return resetTime(c.getTime());
152 | }
153 | //减少一天
154 | public static Date lessenOneDay(Date date) {
155 | Calendar c = Calendar.getInstance();
156 | c.setTime(date);
157 | c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) - 1);
158 | return resetTime(c.getTime());
159 | }
160 | public static String lessenOneDay(String dateStr)throws Exception {
161 | Date date = formatDate(dateStr, DEFAULT_FORMAT_DATE_WITHOUT_TIME);
162 | Calendar c = Calendar.getInstance();
163 | c.setTime(date);
164 | c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) - 1);
165 | SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE_WITHOUT_TIME);
166 | return df.format(resetTime(c.getTime()));
167 | }
168 |
169 | /**
170 | * 把时间除去毫秒显示 add by jian_xie
171 | */
172 | public static String getFormatDateWithoutMillSecond(String time) {
173 | if (time == null || time.trim().length() == 0) {
174 | return null;
175 | }
176 | return time.substring(0, 19);
177 | }
178 |
179 | /*
180 | * 通过年月获取起始时间
181 | */
182 | public static Date getDateFromYearAndMonth(int year, int month){
183 | if(month > 12){
184 | year++;
185 | month -= 12;
186 | }
187 | Date resultDate = new Date(year - 1900, month - 1, 1);
188 | resultDate = resetTime(resultDate);
189 | return resultDate;
190 | }
191 |
192 | /*
193 | * 通过季度获取起始时间
194 | */
195 | public static Date getDateFromSeason(int year, int season){
196 | if(season < 1){
197 | throw new RuntimeException("季度必须大于1");
198 | }
199 | if(season > 4){
200 | year += season / 4;
201 | season = season % 4;
202 | }
203 | int month = (season-1)*3 + 1;
204 | return getDateFromYearAndMonth(year, month);
205 | }
206 |
207 | /*
208 | * 获取某个月的最后一天最后瞬间
209 | */
210 | public static Date getLastMomentOfDay(Date original) {
211 | Calendar calendar = Calendar.getInstance();
212 | calendar.setTime(original);
213 | calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
214 | calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
215 | calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
216 | calendar.set(Calendar.MILLISECOND, 0);//这个超过0的话会被进位,会变成第二天
217 | Date lastDate = calendar.getTime();
218 | return lastDate;
219 | }
220 |
221 | /**
222 | * 格式化(从、开始时间等)时间,方便hql时间查询比较
223 | * add by shiwu_bin 2013-08-05
224 | * */
225 | public static String formateStartTime(String startTime){
226 | return startTime + " 00:00:00";
227 | }
228 |
229 | /**
230 | * 格式化(至、结束时间等)时间,方便hql时间查询比较
231 | * add by shiwu_bin 2013-08-05
232 | * */
233 | public static String formateEndTime(String endTime){
234 | return endTime + " 23:59:59";
235 | }
236 |
237 | /**
238 | * 获取某年某月的最后一天的日期字符串(如2013-08-31)
239 | */
240 | public static String getLastDayText(Integer year, Integer month) {
241 | return formatDate(getLastDay(year,month), DEFAULT_FORMAT_DATE_WITHOUT_TIME +" 23:59:59");
242 | }
243 |
244 | public static Date getLastDay(Integer year, Integer month){
245 | Calendar cal = Calendar.getInstance();
246 | cal.set(Calendar.YEAR, year);
247 | cal.set(Calendar.MONTH, month);
248 | cal.set(Calendar.DAY_OF_MONTH, 1);
249 | cal.add(Calendar.DAY_OF_MONTH, -1);
250 | return cal.getTime();
251 | }
252 | //某月最后一天
253 | public static String getLastDay(String dateStr){
254 | Calendar cal = Calendar.getInstance();
255 | SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE_WITHOUT_TIME);
256 | try {
257 | Date date = formatDate(dateStr,DEFAULT_FORMAT_DATE_WITHOUT_TIME);
258 | cal.setTime(date);
259 | cal.add(Calendar.MONTH, 1);
260 | cal.set(Calendar.DAY_OF_MONTH, 1);
261 | cal.add(Calendar.DAY_OF_MONTH, -1);
262 | } catch (ParseException e) {
263 | e.printStackTrace();
264 | }
265 | return df.format(cal.getTime());
266 | }
267 | /**
268 | * 获取某年某月的第一天的日期字符串(如2013-08-01)
269 | */
270 | public static String getFirstDayText(Integer year, Integer month) {
271 | if(month < 10){
272 | return year + "-0" + month + "-01 00:00:00";
273 | }
274 | return year + "-" + month+"-01" + " 00:00:00";
275 | }
276 |
277 | public static Date getFirstDay(Integer year, Integer month){
278 | try {
279 | return formatDate(year+"-"+month+"-1", DEFAULT_FORMAT_DATE_WITHOUT_TIME);
280 | } catch (Exception e) {
281 | e.printStackTrace();
282 | return null;
283 | }
284 | }
285 | //某月第一天
286 | public static String getFirstDay(String dateStr){
287 | Calendar cal = Calendar.getInstance();
288 | SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE_WITHOUT_TIME);
289 | try {
290 | Date date = formatDate(dateStr,DEFAULT_FORMAT_DATE_WITHOUT_TIME);
291 | cal.setTime(date);
292 | cal.set(Calendar.DAY_OF_MONTH, 1);
293 | } catch (ParseException e) {
294 | e.printStackTrace();
295 | }
296 | return df.format(cal.getTime());
297 | }
298 |
299 | /**
300 | * 获取一个月以前的日期
301 | * */
302 | public static Date getBeforeMonthDate(Date date){
303 | Calendar cal = Calendar.getInstance();
304 | cal.setTime(date);
305 | cal.add(cal.MONTH, -1);
306 | return cal.getTime();
307 | }
308 |
309 | public static Date addOneSecond(Date time){
310 | return new Timestamp(time.getTime() + 1000);
311 | }
312 | /**
313 | * 取所在日期的星期第一天,星期日
314 | * @param args
315 | * weifengdeng 2015-3-10
316 | */
317 | public static Date getFirstWeekDay(Date date){
318 | Calendar cal = Calendar.getInstance();
319 | cal.setTime(date);
320 | cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);//本周第一天,星期日
321 | return cal.getTime();
322 | }
323 | public static Date getFirstWeekDay(String dateStr){
324 | Date date = null;
325 | try {
326 | date = formatDate(dateStr,DEFAULT_FORMAT_DATE_WITHOUT_TIME);
327 | date = getFirstWeekDay(date);
328 | } catch (ParseException e) {
329 | e.printStackTrace();
330 | }
331 | return date;
332 | }
333 | public static String getFirstWeekDayStr(String dateStr){
334 | SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE_WITHOUT_TIME);
335 | return df.format(getFirstWeekDay(dateStr));
336 | }
337 | /**
338 | * 取所在日期的星期最后一天,星期六
339 | * @param args
340 | */
341 | public static Date getLastWeekDay(Date date){
342 | Calendar cal = Calendar.getInstance();
343 | cal.setTime(date);
344 | cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);//本周最后一天,星期六
345 | return cal.getTime();
346 | }
347 | public static Date getLastWeekDay(String dateStr){
348 | Date date = null;
349 | try {
350 | date = formatDate(dateStr,DEFAULT_FORMAT_DATE_WITHOUT_TIME);
351 | date = getLastWeekDay(date);
352 | } catch (ParseException e) {
353 | e.printStackTrace();
354 | }
355 | return date;
356 | }
357 | public static String getLastWeekDayStr(String dateStr){
358 | SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE_WITHOUT_TIME);
359 | return df.format(getLastWeekDay(dateStr));
360 | }
361 | /**
362 | * 取所在日期的季度第一天
363 | * @param args
364 | */
365 | public static Date getFirstQuarter(Date date){
366 | Calendar cal = Calendar.getInstance();
367 | cal.setTime(date);
368 | int month = getQuarterInMonth(cal.get(Calendar.MONTH), true);
369 | cal.set(Calendar.MONTH, month-1);
370 | cal.set(Calendar.DAY_OF_MONTH, 1);
371 | return cal.getTime();
372 | }
373 | public static Date getFirstQuarter(String dateStr){
374 | Date date = null;
375 | try {
376 | date = formatDate(dateStr,DEFAULT_FORMAT_DATE_WITHOUT_TIME);
377 | date = getFirstQuarter(date);
378 | } catch (ParseException e) {
379 | e.printStackTrace();
380 | }
381 | return date;
382 | }
383 | public static String getFirstQuarterStr(String dateStr){
384 | SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE_WITHOUT_TIME);
385 | return df.format(getFirstQuarter(dateStr));
386 | }
387 | /**
388 | * 取所在日期的季度最后一天
389 | * @param args
390 | */
391 | public static Date getLastQuarter(Date date){
392 | Calendar cal = Calendar.getInstance();
393 | cal.setTime(date);
394 | int month = getQuarterInMonth(cal.get(Calendar.MONTH), false);
395 | cal.set(Calendar.MONTH, month);
396 | cal.set(Calendar.DAY_OF_MONTH, 1);
397 | cal.add(Calendar.DAY_OF_MONTH, -1);
398 | return cal.getTime();
399 | }
400 | public static Date getLastQuarter(String dateStr){
401 | Date date = null;
402 | try {
403 | date = formatDate(dateStr,DEFAULT_FORMAT_DATE_WITHOUT_TIME);
404 | date = getLastQuarter(date);
405 | } catch (ParseException e) {
406 | e.printStackTrace();
407 | }
408 | return date;
409 | }
410 | public static String getLastQuarterStr(String dateStr){
411 | SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE_WITHOUT_TIME);
412 | return df.format(getLastQuarter(dateStr));
413 | }
414 | // 返回第几个月份,不是几月
415 | // 季度一年四季, 第一季度:2月-4月, 第二季度:5月-7月, 第三季度:8月-10月, 第四季度:11月-1月
416 | private static int getQuarterInMonth(int month, boolean isQuarterStart) {
417 | int months[] = { 1, 4, 7, 10 };
418 | if (!isQuarterStart) {
419 | months = new int[] { 3, 6, 9, 12 };
420 | }
421 | if (month >= 0 && month < 3)
422 | return months[0];
423 | else if (month >= 3 && month < 6)
424 | return months[1];
425 | else if (month >= 6 && month < 9)
426 | return months[2];
427 | else
428 | return months[3];
429 | }
430 | /**
431 | * 字符串转timestamp
432 | */
433 | public static Timestamp formatTimestamp(String time, String formatStr)throws Exception {
434 | Date date = formatDate(time, formatStr);
435 | Timestamp stamp = new Timestamp(date.getTime());
436 | return stamp;
437 | }
438 | //date 转 timestamp
439 | public static Timestamp formatTimestamp(Date date)throws Exception {
440 | Timestamp stamp = new Timestamp(date.getTime());
441 | return stamp;
442 | }
443 |
444 | public static void main(String[] args){
445 | }
446 |
447 |
448 | }
449 |
--------------------------------------------------------------------------------
/app/src/main/java/yxy/videolineview/MainActivity.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.widget.Toast;
6 |
7 | import java.text.ParseException;
8 | import java.util.ArrayList;
9 | import java.util.Date;
10 | import java.util.List;
11 |
12 | public class MainActivity extends AppCompatActivity {
13 |
14 | VideoLineView videoLineView;
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_main);
20 | videoLineView = findViewById(R.id.videoLineView);
21 | List videoInfoList = new ArrayList();
22 | /*
23 | try {
24 | videoInfoList.add(new VideoInfo(DateUtils.formatDate("2018-06-29 08:30:20",
25 | DateUtils.DEFAULT_FORMAT_DATE),DateUtils.formatDate("2018-06-29 10:26:18",DateUtils.DEFAULT_FORMAT_DATE)));
26 | } catch (ParseException e) {
27 | e.printStackTrace();
28 | }
29 | */
30 | videoInfoList.add(new VideoInfo(new Date(new Date().getTime()-1000*60*60),new Date()));
31 |
32 | videoLineView.setVideoInfos(videoInfoList);
33 | videoLineView.setVideolineChangeListener(new VideoLineViewChangeListener() {
34 | @Override
35 | public void onChange(Date date, VideoLineView videoLineView) {
36 | Toast.makeText(getApplicationContext(),DateUtils.formatDate(date,DateUtils.DEFAULT_FORMAT_DATE),Toast.LENGTH_SHORT).show();
37 | }
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/yxy/videolineview/VideoInfo.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * Created by yang on 2018-07-05.
7 | */
8 |
9 | public class VideoInfo {
10 |
11 | private Date startTime;
12 | private Date endTime;
13 |
14 | public VideoInfo(){}
15 |
16 | public VideoInfo(Date startTime, Date endTime){
17 | this.startTime = startTime;
18 | this.endTime =endTime;
19 | }
20 |
21 | public Date getStartTime() {
22 | return startTime;
23 | }
24 |
25 | public void setStartTime(Date startTime) {
26 | this.startTime = startTime;
27 | }
28 |
29 | public Date getEndTime() {
30 | return endTime;
31 | }
32 |
33 | public void setEndTime(Date endTime) {
34 | this.endTime = endTime;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/yxy/videolineview/VideoLineView.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.os.Handler;
9 | import android.support.annotation.Nullable;
10 | import android.util.AttributeSet;
11 | import android.view.MotionEvent;
12 | import android.view.View;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Date;
16 | import java.util.List;
17 |
18 | /**
19 | * Created by yang on 2018-07-05.
20 | * 自定义视频时间轴
21 | *
22 | */
23 |
24 | public class VideoLineView extends View {
25 | //中间线颜色
26 | private int mCenterlineColor;
27 | //刻度线颜色
28 | private int mLineColor;
29 | //文字颜色
30 | private int mTextColor;
31 | //视频段的背景颜色
32 | private int mVideoColor;
33 | //视频轴的背景颜色
34 | private int mBgColor;
35 | //文字大小
36 | private int mTextSize;
37 | //当前刻度时间
38 | private Date mTime = new Date();
39 | private int mHeight;
40 | private int mWidth;
41 | private int intervalWidth=30;//每个刻度30dp宽度
42 | private int intervalMinute=10;//每个刻度表示10分钟
43 | Paint paint = new Paint();
44 | private List videoInfos = new ArrayList();
45 | private float mStartX = 0;
46 | private VideoLineViewChangeListener videoLineViewChangeListener;
47 | private boolean autoRun = true;//是否自动改变时间
48 | private Object data;//用来绑定用户数据
49 | private Handler handler = new Handler() {
50 | };
51 | private Runnable autoRunTime = new Runnable() {
52 | @Override
53 | public void run() {
54 | if(mTime!=null&&mTime.getTime() getVideoInfos() {
94 | return videoInfos;
95 | }
96 |
97 | public void setVideoInfos(List videoInfos) {
98 | this.videoInfos = videoInfos;
99 | if(videoInfos!=null&&!videoInfos.isEmpty()){
100 | setmTime(videoInfos.get(0).getStartTime());
101 | }
102 | }
103 |
104 | public boolean isAutoRun() {
105 | return autoRun;
106 | }
107 |
108 | public void setAutoRun(boolean autoRun) {
109 | this.autoRun = autoRun;
110 | }
111 |
112 | public VideoLineViewChangeListener getVideoLineViewChangeListener() {
113 | return videoLineViewChangeListener;
114 | }
115 |
116 | public void setVideolineChangeListener(VideoLineViewChangeListener videoLineViewChangeListener) {
117 | this.videoLineViewChangeListener = videoLineViewChangeListener;
118 | }
119 |
120 | public Object getData() {
121 | return data;
122 | }
123 |
124 | public VideoLineView setData(Object data) {
125 | this.data = data;
126 | return this;
127 | }
128 |
129 | @Override
130 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
131 | super.onLayout(changed, left, top, right, bottom);
132 | mHeight = getHeight();
133 | mWidth = getWidth();
134 | }
135 |
136 | @Override
137 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
138 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
139 | mHeight = measureVideoLine(heightMeasureSpec);
140 | mWidth = measureVideoLine(widthMeasureSpec);
141 | setMeasuredDimension(mWidth,mHeight);
142 | }
143 |
144 | private int measureVideoLine(int measureSpec) {
145 | int result = 0;
146 | int specMode = MeasureSpec. getMode(measureSpec);
147 | int specSize = MeasureSpec. getSize(measureSpec);
148 | switch (specMode) {
149 | case MeasureSpec. AT_MOST:
150 | result = ConvertUtils.dp2px(getContext(),80);//默认80dp
151 | break;
152 | case MeasureSpec. EXACTLY:
153 | result = Math.max(specSize,ConvertUtils.dp2px(getContext(),80));
154 | break;
155 | }
156 | return result;
157 | }
158 |
159 | @Override
160 | public boolean onTouchEvent(MotionEvent event) {
161 | switch (event.getAction()){
162 | case MotionEvent.ACTION_DOWN:
163 | mStartX = event.getX();
164 | break;
165 | case MotionEvent.ACTION_MOVE:
166 | case MotionEvent.ACTION_UP:
167 | float distance = event.getX()-mStartX;
168 | long zeng = getTimeByDistance(distance);
169 | mStartX = event.getX();
170 | mTime.setTime(mTime.getTime()-zeng);
171 | invalidate();
172 | if(event.getAction()== MotionEvent.ACTION_UP){
173 | if(videoLineViewChangeListener!=null){
174 | videoLineViewChangeListener.onChange(mTime,this);
175 | }
176 | startRunTime();
177 | }
178 | break;
179 | }
180 | return true;
181 | }
182 |
183 | @Override
184 | protected void onDraw(Canvas canvas) {
185 | paint.setColor(mBgColor);//首先绘制背景颜色
186 | canvas.drawRect(0,0,mWidth,mHeight,paint);
187 | String time = DateUtils.formatDate(mTime, DateUtils.DEFAULT_FORMAT_DATE);
188 | //绘制时间
189 | paint.setColor(mTextColor);
190 | paint.setTextSize(mTextSize);
191 | float v = paint.measureText(time);
192 | float offset = paint.measureText(time.substring(9,10))+paint.measureText(" ")/2;
193 | Paint.FontMetrics fontMetrics = paint.getFontMetrics();
194 | float value = fontMetrics.bottom - fontMetrics.top;
195 | canvas.drawText(time,(mWidth-v)/2-offset,value,paint);
196 | //绘制含视频区域
197 | paint.setColor(mVideoColor);
198 | for (VideoInfo recordInfo : videoInfos) {
199 | if(recordInfo.getStartTime()!=null&&recordInfo.getEndTime()!=null){
200 | long start = recordInfo.getStartTime().getTime();
201 | long end = recordInfo.getEndTime().getTime();
202 | if(end<=start) continue;
203 | float s = getXByTime(recordInfo.getStartTime());
204 | float e = getXByTime(recordInfo.getEndTime());
205 | if(e>0||e>mWidth) {
206 | canvas.drawRect(s < 0 ? 0 : s, mHeight / 2 - 30, e > mWidth ? mWidth : e, mHeight / 2 - 10, paint);
207 | }
208 | }
209 | }
210 | paint.setColor(mLineColor);
211 | //绘制刻度尺
212 | canvas.drawLine(0,mHeight/2,mWidth,mHeight/2,paint);
213 | //往左绘制
214 | drawLine(canvas,paint,mTime.getTime(),mWidth/2,true);
215 | //往右绘制
216 | drawLine(canvas,paint,mTime.getTime(),mWidth/2,false);
217 | //中间线最后绘制
218 | paint.setColor(mCenterlineColor);
219 | canvas.drawLine(mWidth/2,0,mWidth/2,mHeight,paint);
220 | }
221 |
222 | private void drawLine(Canvas canvas, Paint paint, long time, float startX, boolean left){
223 | paint.setColor(mLineColor);
224 | long residue = time%(60*1000*intervalMinute);
225 | long nextTime = 0;
226 | float offset = ConvertUtils.dp2px(getContext(),intervalWidth);
227 | if(residue==0){
228 | nextTime = left?time-60*1000*intervalMinute:time+60*1000*intervalMinute;
229 | startX = left?startX-offset:startX+offset;
230 | }else{
231 | nextTime = left?time-residue:time-residue+60*1000*intervalMinute;
232 | //重新计算startX;
233 | float v = offset / (60 * 10);//计算出每一秒的距离
234 | startX=left?startX-residue/1000*v:startX+(60*1000*intervalMinute-residue)/1000*v;
235 | }
236 | if(startX<0||startX>mWidth){
237 | return;
238 | }
239 | int endY = nextTime%(3600*1000)==0?10:5;
240 | canvas.drawLine(startX,mHeight/2,startX,mHeight/2+ConvertUtils.dp2px(getContext(),endY),paint);
241 | if(endY==10){
242 | Date t = new Date(nextTime);
243 | float v = paint.measureText(t.getHours()+":00");
244 | Paint.FontMetrics fontMetrics = paint.getFontMetrics();
245 | float value = fontMetrics.bottom - fontMetrics.top;
246 | paint.setColor(mTextColor);
247 | canvas.drawText(t.getHours()+":00",startX-v/2,mHeight/2+value+10,paint);
248 | }
249 | drawLine(canvas,paint,nextTime,startX,left);
250 | }
251 |
252 |
253 | /**
254 | * 根据时间获取该时间在当前数轴的X坐标
255 | * @param date
256 | * @return
257 | */
258 | private float getXByTime(Date date){
259 | float offset_px = ConvertUtils.dp2px(getContext(),intervalWidth);
260 | float secondsWidth = offset_px / (60 * 10);
261 | long s = (date.getTime()-mTime.getTime())/1000;
262 | float x = mWidth/2.0f+s*secondsWidth;
263 | return x;
264 | }
265 |
266 | private int getTimeByDistance(float distance){
267 | float offset_px = ConvertUtils.dp2px(getContext(),intervalWidth);
268 | float secondsWidth = offset_px / (60 * 10);
269 | return Math.round(distance/secondsWidth)*1000;
270 | }
271 |
272 | /**
273 | * 开启自动计时 前提autoRun=true
274 | * 由于海康调用sdk需要一定的时间 所以建议在海康调用完毕后再调用setmTime方法 同步时间
275 | */
276 | public void startRunTime(){
277 | handler.removeCallbacks(autoRunTime);
278 | if(autoRun&&videoInfos!=null&&!videoInfos.isEmpty()){
279 | handler.postDelayed(autoRunTime,1000);
280 | }
281 | }
282 |
283 | public void stopRunTime(){
284 | handler.removeCallbacks(autoRunTime);
285 | }
286 |
287 | }
288 |
--------------------------------------------------------------------------------
/app/src/main/java/yxy/videolineview/VideoLineViewChangeListener.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * Created by yang on 2018-07-05.
7 | */
8 |
9 | public interface VideoLineViewChangeListener {
10 | void onChange(Date date, VideoLineView videoLineView);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VideoLineView
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/yxy/videolineview/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package yxy.videolineview;
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() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.1'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## Project-wide Gradle settings.
2 | #
3 | # For more details on how to configure your build environment visit
4 | # http://www.gradle.org/docs/current/userguide/build_environment.html
5 | #
6 | # Specifies the JVM arguments used for the daemon process.
7 | # The setting is particularly useful for tweaking memory settings.
8 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | #
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | #Fri Jul 06 17:38:44 CST 2018
16 | systemProp.http.proxyHost=127.0.0.1
17 | org.gradle.jvmargs=-Xmx1536m
18 | systemProp.http.proxyPort=10068
19 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdoer/VideoLineView/ee14f6be5d95e611aaeb5a9a3c82d5b1d25f86be/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jul 06 17:38:36 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/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 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
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 Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------