├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.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
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ └── activity_main.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── caveman
│ │ │ └── androidtimeaxis
│ │ │ ├── TimeInfo.java
│ │ │ ├── MainActivity.java
│ │ │ └── ListAdapter.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── caveman
│ │ │ └── androidtimeaxis
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── caveman
│ │ └── androidtimeaxis
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── timeaxis
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── attr.xml
│ │ │ ├── drawable
│ │ │ │ └── ic_circle.xml
│ │ │ └── layout
│ │ │ │ └── list_item.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── caveman
│ │ │ └── timeaxis
│ │ │ ├── holder
│ │ │ └── CommonViewHolder.java
│ │ │ ├── adapter
│ │ │ └── TimeAxisAdapter.java
│ │ │ └── weight
│ │ │ └── TimeAxisView.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── caveman
│ │ │ └── timeaxis
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── caveman
│ │ └── timeaxis
│ │ └── ExampleInstrumentedTest.java
├── build.gradle
└── proguard-rules.pro
├── settings.gradle
├── image
└── 20181027223219.jpg
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .idea
├── caches
│ └── build_file_checksums.ser
├── encodings.xml
├── vcs.xml
├── runConfigurations.xml
├── gradle.xml
├── misc.xml
├── codeStyles
│ └── Project.xml
├── assetWizardSettings.xml
└── inspectionProfiles
│ └── Project_Default.xml
├── .gitignore
├── gradle.properties
├── gradlew.bat
├── README.md
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/timeaxis/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':timeaxis'
2 |
--------------------------------------------------------------------------------
/image/20181027223219.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/image/20181027223219.jpg
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AndroidTimeAxis
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tomzem/AndroidTimeAxis/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/timeaxis/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TimeAxis
3 | 2018-08-08 23:23:32
4 |
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/libraries
5 | /.idea/modules.xml
6 | /.idea/workspace.xml
7 | .DS_Store
8 | /build
9 | /captures
10 | .externalNativeBuild
11 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/timeaxis/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/timeaxis/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Oct 25 09:31:26 GMT+08:00 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.4-all.zip
7 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/timeaxis/src/main/res/drawable/ic_circle.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/timeaxis/src/test/java/com/caveman/timeaxis/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.caveman.timeaxis;
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 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/caveman/androidtimeaxis/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.caveman.androidtimeaxis;
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 | }
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/timeaxis/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/timeaxis/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 28
5 |
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion 15
10 | targetSdkVersion 28
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 |
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation 'com.android.support:appcompat-v7:28.0.0'
29 | implementation 'com.android.support:recyclerview-v7:28.0.0'
30 | implementation 'com.github.bumptech.glide:glide:3.8.0'
31 | }
32 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/timeaxis/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/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/timeaxis/src/androidTest/java/com/caveman/timeaxis/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.caveman.timeaxis;
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.caveman.timeaxis.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.caveman.androidtimeaxis"
7 | minSdkVersion 15
8 | targetSdkVersion 28
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 | buildToolsVersion '28.0.2'
20 | }
21 |
22 | dependencies {
23 | implementation fileTree(include: ['*.jar'], dir: 'libs')
24 | implementation 'com.android.support:appcompat-v7:28.0.0'
25 | implementation project(path: ':timeaxis')
26 | implementation 'com.android.support:recyclerview-v7:28.0.0'
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/caveman/androidtimeaxis/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.caveman.androidtimeaxis;
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.caveman.androidtimeaxis", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/timeaxis/src/main/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
19 |
20 |
25 |
26 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/caveman/androidtimeaxis/TimeInfo.java:
--------------------------------------------------------------------------------
1 | package com.caveman.androidtimeaxis;
2 |
3 | /**
4 | * Created by Administrator on 2018/10/26.
5 | *
6 | * Description:
7 | */
8 | public class TimeInfo {
9 | private String msg;
10 | private String smallText;
11 | private String bigText;
12 | private String imagePath;
13 | // 1 未完成 0 进行 -1 已完成
14 | private int state = 1;
15 |
16 | public TimeInfo() {
17 | }
18 |
19 | public TimeInfo(String msg, String smallText, String bigText, String imagePath, int state) {
20 | this.msg = msg;
21 | this.smallText = smallText;
22 | this.bigText = bigText;
23 | this.imagePath = imagePath;
24 | this.state = state;
25 | }
26 |
27 | public String getMsg() {
28 | return msg;
29 | }
30 |
31 | public void setMsg(String msg) {
32 | this.msg = msg;
33 | }
34 |
35 | public String getSmallText() {
36 | return smallText;
37 | }
38 |
39 | public void setSmallText(String smallText) {
40 | this.smallText = smallText;
41 | }
42 |
43 | public String getBigText() {
44 | return bigText;
45 | }
46 |
47 | public void setBigText(String bigText) {
48 | this.bigText = bigText;
49 | }
50 |
51 | public String getImagePath() {
52 | return imagePath;
53 | }
54 |
55 | public void setImagePath(String imagePath) {
56 | this.imagePath = imagePath;
57 | }
58 |
59 | public int getState() {
60 | return state;
61 | }
62 |
63 | public void setState(int state) {
64 | this.state = state;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/.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 |
34 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.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 |
--------------------------------------------------------------------------------
/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/java/com/caveman/androidtimeaxis/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.caveman.androidtimeaxis;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 |
8 | import com.caveman.timeaxis.adapter.TimeAxisAdapter;
9 | import com.caveman.timeaxis.weight.TimeAxisView;
10 |
11 | import java.sql.Time;
12 | import java.util.ArrayList;
13 | import java.util.HashMap;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | public class MainActivity extends AppCompatActivity {
18 |
19 | private RecyclerView mRwList;
20 | private ListAdapter timeAdapter;
21 | private List data;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_main);
27 |
28 | initData();
29 | mRwList = findViewById(R.id.my_recycler_view);
30 | timeAdapter = new ListAdapter(data, this, R.layout.list_item);
31 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
32 | linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
33 | mRwList.setLayoutManager(linearLayoutManager);
34 | mRwList.setAdapter(timeAdapter);
35 | }
36 |
37 | private void initData() {
38 | data = new ArrayList<>();
39 | data.add(new TimeInfo("订单提交成功","2018/10/27","13:05","",1));
40 | data.add(new TimeInfo("订单已支付","2018/10/27","13:05","",1));
41 | data.add(new TimeInfo("商家已接单","2018/10/27","13:05","",1));
42 | data.add(new TimeInfo("骑手已接单","2018/10/27","13:11","",1));
43 | data.add(new TimeInfo("骑手已到店","2018/10/27","13:16","",1));
44 | data.add(new TimeInfo("骑手已取货","2018/10/27","13:22","",1));
45 | data.add(new TimeInfo("骑手正在送货","","","https://avatars3.githubusercontent.com/u/32257815?s=64&v=4",0));
46 | data.add(new TimeInfo("商品已送达","","","",-1));
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/.idea/assetWizardSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/caveman/androidtimeaxis/ListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.caveman.androidtimeaxis;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.widget.ImageView;
6 |
7 | import com.caveman.timeaxis.holder.CommonViewHolder;
8 | import com.caveman.timeaxis.adapter.TimeAxisAdapter;
9 | import com.caveman.timeaxis.weight.TimeAxisView;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * Created by Administrator on 2018/10/26.
15 | *
16 | * Description:
17 | */
18 | public class ListAdapter extends TimeAxisAdapter {
19 |
20 | public ListAdapter(List mDataSource, Context mContext) {
21 | super(mDataSource, mContext);
22 | }
23 |
24 | /**
25 | *
26 | * @param mDataSource 数据源
27 | * @param mContext
28 | * @param resID 自定义item布局
29 | */
30 | public ListAdapter(List mDataSource, Context mContext, int resID) {
31 | super(mDataSource, mContext, resID);
32 | }
33 |
34 | /**
35 | * 相当于RecyclerView.Adapter的onBindViewHolder方法
36 | * @param holder
37 | * @param position
38 | */
39 | @Override
40 | protected void initView(CommonViewHolder holder, int position) {
41 | TimeInfo timeInfo = mDataSource.get(position);
42 |
43 | TimeAxisView mTimeAxisView = holder.getView(com.caveman.timeaxis.R.id.tav_line);
44 | mTimeAxisView.setBigText(timeInfo.getBigText());
45 | mTimeAxisView.setSmallText(timeInfo.getSmallText());
46 | //根据状态设置圆圈样式
47 | if (timeInfo.getState() == 1){
48 | mTimeAxisView.setCircleShape(TimeAxisView.SOLID_CIRCLE);
49 | }else if(timeInfo.getState() == 0){
50 | mTimeAxisView.setCircleShape(TimeAxisView.CENTER_CIRCLE);
51 | }else{
52 | mTimeAxisView.setCircleShape(TimeAxisView.HOLLOW_CIRCLE);
53 | }
54 |
55 | ImageView imageView = holder.getView(R.id.img_content);
56 | if (timeInfo.getImagePath().isEmpty()){
57 | imageView.setVisibility(View.GONE);
58 | }else{
59 | imageView.setVisibility(View.VISIBLE);
60 | holder.setImageByUrl(R.id.img_content, timeInfo.getImagePath());
61 | }
62 |
63 | holder.setText(R.id.tv_content, timeInfo.getMsg());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/timeaxis/src/main/java/com/caveman/timeaxis/holder/CommonViewHolder.java:
--------------------------------------------------------------------------------
1 | package com.caveman.timeaxis.holder;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.text.Html;
7 | import android.util.SparseArray;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.bumptech.glide.Glide;
13 |
14 | /**
15 | * Created by Administrator on 2018/10/26.
16 | *
17 | * Description:
18 | */
19 | public class CommonViewHolder extends RecyclerView.ViewHolder{
20 |
21 | private View mContentView;
22 |
23 | private SparseArray mSparseArray = new SparseArray<>();
24 |
25 | private Context mContext;
26 |
27 | public CommonViewHolder(View itemView, Context context) {
28 | super(itemView);
29 | this.mContentView = itemView;
30 | this.mContext = context;
31 | }
32 |
33 | public View getContentView() {
34 | return mContentView;
35 | }
36 |
37 | /**
38 | * 通过控件的Id获取对于的控件,如果没有则加入mSparseArray
39 | *
40 | * @param id
41 | * @param
42 | * @return
43 | */
44 | public T getView(int id) {
45 | View view = mSparseArray.get(id);
46 | if (view == null) {
47 | view = mContentView.findViewById(id);
48 | mSparseArray.append(id, view);
49 | }
50 | return (T) view;
51 | }
52 |
53 | /**
54 | * 为TextView设置数据
55 | *
56 | * @param id
57 | * @param text
58 | * @return
59 | */
60 | public CommonViewHolder setText(int id, String text) {
61 | TextView view = getView(id);
62 | view.setText(Html.fromHtml(text));
63 | return this;
64 | }
65 |
66 | public CommonViewHolder setImageByUrl(int id, String url) {
67 | ImageView view = getView(id);
68 | Glide.with(mContext).load(url).into(view);
69 | return this;
70 | }
71 |
72 | public CommonViewHolder setImageResource(int id, int resId) {
73 | ImageView view = getView(id);
74 | view.setImageResource(resId);
75 | return this;
76 | }
77 |
78 | public CommonViewHolder setImageBitmap(int id, Bitmap bitmap) {
79 | ImageView view = getView(id);
80 | view.setImageBitmap(bitmap);
81 | return this;
82 | }
83 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/timeaxis/src/main/java/com/caveman/timeaxis/adapter/TimeAxisAdapter.java:
--------------------------------------------------------------------------------
1 | package com.caveman.timeaxis.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.ViewGroup;
7 |
8 | import com.caveman.timeaxis.R;
9 | import com.caveman.timeaxis.holder.CommonViewHolder;
10 | import com.caveman.timeaxis.weight.TimeAxisView;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * Created by Administrator on 2018/10/25.
16 | *
17 | * Description:
18 | */
19 | public abstract class TimeAxisAdapter extends RecyclerView.Adapter{
20 |
21 | protected List mDataSource;
22 | private Context mContext;
23 | private int resID = R.layout.list_item;
24 |
25 | public TimeAxisAdapter(List mDataSource, Context mContext) {
26 | this.mDataSource = mDataSource;
27 | this.mContext = mContext;
28 | }
29 |
30 | public TimeAxisAdapter(List mDataSource, Context mContext, int resID) {
31 | this.mDataSource = mDataSource;
32 | this.mContext = mContext;
33 | this.resID = resID;
34 | }
35 |
36 | @Override
37 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
38 | return new CommonViewHolder(LayoutInflater.from(mContext).inflate(resID, null),mContext);
39 | }
40 |
41 | @Override
42 | public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
43 | CommonViewHolder holder = (CommonViewHolder)viewHolder;
44 | if (resID == R.layout.list_item){
45 | TimeAxisView mTimeAxisView = holder.getView(R.id.tav_line);
46 | if (position == 0){
47 | mTimeAxisView.isHeadView(true);
48 | }else{
49 | mTimeAxisView.isHeadView(false);
50 | }
51 | if (position == mDataSource.size()-1){
52 | mTimeAxisView.isFootView(true);
53 | }else{
54 | mTimeAxisView.isFootView(false);
55 | }
56 | }
57 | initView(holder, position);
58 | }
59 |
60 | protected abstract void initView(CommonViewHolder holder, int position);
61 |
62 | @Override
63 | public int getItemCount() {
64 | return mDataSource == null ? 0 : mDataSource.size();
65 | }
66 |
67 | public void refresh(List dataSource) {
68 | mDataSource = dataSource;
69 | this.notifyDataSetChanged();
70 | }
71 |
72 | public void deleteList(int position) {
73 | mDataSource.remove(position);
74 | this.notifyDataSetChanged();
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AndroidTimeAxis [](https://jitpack.io/#Tomzem/AndroidTimeAxis)
2 |
3 | 🍎利用RecyclerView实现时间轴,支持自定义布局
4 |
5 | ## 使用说明
6 | ### 依赖
7 | Step 1. Add it in your root build.gradle at the end of repositories:
8 | ```
9 | allprojects {
10 | repositories {
11 | ...
12 | maven { url 'https://jitpack.io' }
13 | }
14 | }
15 | ```
16 | Step 2. Add the dependency
17 | ```
18 | dependencies {
19 | implementation 'com.github.Tomzem:AndroidTimeAxis:1.0.0'
20 | }
21 | ```
22 | ### 调用
23 | 1.布局文件中只需要一个RecyclerView:
24 | ```
25 |
30 | ```
31 | 2.需要继承TimeAxisAdapter重写Adapter:
32 | ```
33 | public ListAdapter(List mDataSource, Context mContext) {
34 | super(mDataSource, mContext);
35 | }
36 |
37 | /**
38 | * @param mDataSource 数据源
39 | * @param mContext
40 | * @param resID 自定义item布局
41 | */
42 | public ListAdapter(List mDataSource, Context mContext, int resID) {
43 | super(mDataSource, mContext, resID);
44 | }
45 |
46 | /**
47 | * 相当于RecyclerView.Adapter的onBindViewHolder方法
48 | * @param holder
49 | * @param position
50 | */
51 | @Override
52 | protected void initView(CommonViewHolder holder, int position) {
53 | }
54 | ```
55 | 3.自定义item(可以省略),布局中需要包含TimeAxisView控件:
56 | ```
57 |
61 | ```
62 | 4.将Adapter设置到RecyclerView当中即可:
63 | ```
64 | mRwList = findViewById(R.id.my_recycler_view);
65 | timeAdapter = new ListAdapter(data, this, R.layout.list_item);
66 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
67 | linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
68 | mRwList.setLayoutManager(linearLayoutManager);
69 | mRwList.setAdapter(timeAdapter);
70 | ```
71 | ## 实际效果
72 | 
73 | ## TimeAxisView方法说明
74 | | 方法名称 | 含 义 |
75 | | -------- | ----- |
76 | | setLineWidth(float width) | 设置时间轴线宽 |
77 | | setLineColor(int resourceId) | 设置时间轴线颜色 |
78 | | isHeadView(boolean isHead) | 设置是否为第一个节点(自定义Item布局需要) |
79 | | isFootView(boolean isFoot) | 设置是否为最后一个节点(自定义Item布局需要) |
80 | | setPointColor(int resourceId) | 设置节点颜色 |
81 | | setPointRadius(float size) | 设置节点圆半径 |
82 | | setCircleShape(int shape) | 设置节点圆类型(SOLID_CIRCLE,HOLLOW_CIRCLE,CENTER_CIRCLE) |
83 | | setBigTextSize(float size) | 设置左侧大字尺寸 |
84 | | setSmallTextSize(float size) | 设置左侧小字尺寸 |
85 | | setSmallText(String text) | 设置左侧小字文本(默认无) |
86 | | setBigText(String text) | 设置左侧大字文本(默认无) |
87 | | setTextColor(int resourceId) | 设置左侧文本颜色 |
88 | ## 自定义属性
89 | | 属性名称 | 含 义 |
90 | | -------- | ----- |
91 | | line_width | 设置时间轴线宽 |
92 | | line_color | 设置时间轴线颜色 |
93 | | point_size | 设置节点圆半径 |
94 | | point_color | 设置节点颜色 |
95 | | text_color | 设置左侧文本颜色 |
96 | | big_text_size | 设置左侧大字尺寸 |
97 | | small_text_size | 设置左侧小字尺寸 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/timeaxis/src/main/java/com/caveman/timeaxis/weight/TimeAxisView.java:
--------------------------------------------------------------------------------
1 | package com.caveman.timeaxis.weight;
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.LinearGradient;
8 | import android.graphics.Paint;
9 | import android.graphics.Rect;
10 | import android.support.annotation.Nullable;
11 | import android.util.AttributeSet;
12 | import android.util.Log;
13 | import android.view.View;
14 | import android.view.WindowManager;
15 |
16 | import com.caveman.timeaxis.R;
17 |
18 | /**
19 | * Created by Administrator on 2018/10/25.
20 | *
21 | * Description:时间轴
22 | */
23 | public class TimeAxisView extends View {
24 | private static final String TAG = "TimeAxisView";
25 |
26 | public static final int SOLID_CIRCLE = 0;
27 | public static final int HOLLOW_CIRCLE = 1;
28 | public static final int CENTER_CIRCLE = 2;
29 |
30 | public static final int GRAVITY_VERTICAL = 1;
31 | public static final int GRAVITY_HORIZONTAL = -1;
32 |
33 | private Paint mLinePaint; // 线画笔
34 | private Paint mPointPaint; // 点画笔
35 | private Paint mTextPaint; //字画笔
36 | private Context mContext;
37 |
38 | private float mLineWidth = 5; //线宽
39 | private int mLineColor = 0; //线得颜色
40 | private int mCircleImage = 0; //关键点图标
41 | private float mCircleRadius = 0; //圆圈半径
42 | private int mPointColor = 0;
43 | private int mTextColor = 0;
44 | private float mSmallTextSize = 35;
45 | private float mBigTextSize = 45;
46 |
47 | // 中心圆类型
48 | private int CIRCLE_SHAPE = SOLID_CIRCLE;
49 | // 横轴or竖轴
50 | private int GRAVITY = GRAVITY_VERTICAL;
51 |
52 | private boolean isHeadPoint = false;
53 | private boolean isFootPoint = false;
54 |
55 | private float width;
56 | private float height;
57 | private float start; //画线轴得起点
58 | private String mBigText = "";
59 | private String mSmallText = "";
60 | private int defaultSize = 100;
61 |
62 | public TimeAxisView(Context context) {
63 | this(context, null);
64 | }
65 |
66 | public TimeAxisView(Context context, AttributeSet attrs) {
67 | this(context, attrs, 0);
68 | }
69 |
70 | public TimeAxisView(Context context, AttributeSet attrs, int defStyleAttr) {
71 | super(context, attrs, defStyleAttr);
72 | mContext = context;
73 | TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TimeAxisView);
74 | try {
75 | if (ta != null){
76 | mLineWidth = ta.getDimension(R.styleable.TimeAxisView_line_width, 5);
77 | mLineColor = ta.getColor(R.styleable.TimeAxisView_line_color, getResources().getColor(R.color.colorAccent));
78 | mCircleImage = ta.getResourceId(R.styleable.TimeAxisView_circle_image, 0);
79 | mCircleRadius = ta.getResourceId(R.styleable.TimeAxisView_point_size, 0);
80 | mPointColor = ta.getColor(R.styleable.TimeAxisView_point_color, getResources().getColor(R.color.colorAccent));
81 | mTextColor = ta.getColor(R.styleable.TimeAxisView_text_color, getResources().getColor(R.color.colorAccent));
82 | mBigTextSize = ta.getDimension(R.styleable.TimeAxisView_big_text_size, 45);
83 | mSmallTextSize = ta.getDimension(R.styleable.TimeAxisView_small_text_size, 35);
84 | }
85 | }finally {
86 | ta.recycle();
87 | }
88 | initView();
89 | }
90 |
91 | private void initView() {
92 | mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
93 | mLinePaint.setStyle(Paint.Style.FILL);
94 |
95 | mPointPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
96 |
97 | mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
98 | mTextPaint.setStyle(Paint.Style.FILL);
99 | }
100 |
101 | @Override
102 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
103 | setMeasuredDimension(getProperSize(widthMeasureSpec), getProperSize(heightMeasureSpec));
104 | }
105 |
106 | private int getProperSize( int measureSpec){
107 | int properSize = defaultSize;
108 | int mode = MeasureSpec.getMode(measureSpec);
109 | int size = MeasureSpec.getSize(measureSpec);
110 | switch (mode){
111 | case MeasureSpec.UNSPECIFIED:
112 | // 没有指定大小,设置为默认大小
113 | properSize = defaultSize;
114 | break;
115 | case MeasureSpec.EXACTLY:
116 | // 固定大小,无需更改其大小
117 | properSize = size;
118 | break;
119 | case MeasureSpec.AT_MOST:
120 | // 此处该值可以取小于等于最大值的任意值,此处取最大值的1/4
121 | properSize = size / 4;
122 | }
123 |
124 | return properSize;
125 | }
126 |
127 | @Override
128 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
129 | super.onLayout(changed, left, top, right, bottom);
130 | }
131 |
132 | @Override
133 | protected void onDraw(Canvas canvas) {
134 | super.onDraw(canvas);
135 |
136 | if (mCircleRadius == 0){
137 | mCircleRadius = mLineWidth * 2;
138 | }
139 | Gravity(GRAVITY);
140 | mLinePaint.setColor(mLineColor);
141 | mLinePaint.setStrokeWidth(mLineWidth);
142 |
143 | if (!isHeadPoint){
144 | if (GRAVITY == GRAVITY_VERTICAL){
145 | canvas.drawLine(start, 0, start, getHeight()/2-mCircleRadius, mLinePaint);
146 | }else{
147 | canvas.drawLine(0, start, getWidth()/2 - mCircleRadius, start, mLinePaint);
148 | }
149 | }
150 | if (!isFootPoint) {
151 | if (GRAVITY == GRAVITY_VERTICAL){
152 | canvas.drawLine(start, getHeight() / 2+mCircleRadius, start, getHeight(), mLinePaint);
153 | }else{
154 | canvas.drawLine(getWidth()/2 + mCircleRadius, start, getWidth(), start, mLinePaint);
155 | }
156 | }
157 |
158 | mPointPaint.setColor(mPointColor);
159 | switch (CIRCLE_SHAPE){
160 | case SOLID_CIRCLE:
161 | mPointPaint.setStyle(Paint.Style.FILL);
162 | break;
163 | case HOLLOW_CIRCLE:
164 | mPointPaint.setStyle(Paint.Style.STROKE);
165 | break;
166 | case CENTER_CIRCLE:
167 | mPointPaint.setStyle(Paint.Style.FILL);
168 | mPointPaint.setStrokeWidth(mLineWidth/2);
169 | canvas.drawCircle(start, getHeight()/2, mCircleRadius/2, mPointPaint);
170 | mPointPaint.setStyle(Paint.Style.STROKE);
171 | break;
172 | }
173 | mPointPaint.setStrokeWidth(mLineWidth/2);
174 | canvas.drawCircle(start, getHeight()/2, mCircleRadius, mPointPaint);
175 | drawLeftText(canvas);
176 | }
177 |
178 |
179 |
180 | private void drawLeftText(Canvas canvas) {
181 | mTextPaint.setColor(mTextColor);
182 | if (!mSmallText.isEmpty()){
183 | mTextPaint.setTextSize(mSmallTextSize);
184 | Rect bounds = new Rect();
185 | mTextPaint.getTextBounds(mSmallText, 0, mSmallText.length(), bounds);
186 | canvas.drawText(mSmallText, start - bounds.width() - mCircleRadius*2 , getHeight()/2 + bounds.height(), mTextPaint);
187 | }
188 | if (!mBigText.isEmpty()){
189 | mTextPaint.setTextSize(mBigTextSize);
190 | Rect bounds = new Rect();
191 | mTextPaint.getTextBounds(mBigText, 0, mBigText.length(), bounds);
192 | canvas.drawText(mBigText, start - bounds.width() - mCircleRadius*2 , getHeight()/2, mTextPaint);
193 | }
194 | }
195 |
196 | private void Gravity(int gravity){
197 | switch (GRAVITY){
198 | case GRAVITY_VERTICAL:
199 | start = getWidth() - mLineWidth -mCircleRadius ;
200 | break;
201 | case GRAVITY_HORIZONTAL:
202 | start = (getHeight() - mLineWidth)/2 + mCircleRadius/4;
203 | break;
204 | }
205 | }
206 |
207 | /**
208 | * 设置线宽
209 | * @param width 直线轴宽
210 | */
211 | public void setLineWidth(float width){
212 | this.mLineWidth = width;
213 | update();
214 | }
215 |
216 | /**
217 | * 设置线颜色
218 | * @param resourceId 直线轴颜色
219 | */
220 | public void setLineColor(int resourceId){
221 | this.mLineColor = getResources().getColor(resourceId);
222 | update();
223 | }
224 |
225 | /**
226 | * 设置圆圈类型
227 | * @param shape 中心园类型
228 | */
229 | public void setCircleShape(int shape){
230 | this.CIRCLE_SHAPE = shape;
231 | update();
232 | }
233 |
234 | /**
235 | * 头部关键点
236 | * @param isHead
237 | */
238 | public void isHeadView(boolean isHead){
239 | this.isHeadPoint = isHead;
240 | update();
241 | }
242 |
243 | /**
244 | * 足部关键点
245 | * @param isFoot
246 | */
247 | public void isFootView(boolean isFoot){
248 | this.isFootPoint = isFoot;
249 | update();
250 | }
251 |
252 | /**
253 | * 横竖展示
254 | * @param gravity (暂不开放)
255 | */
256 | private void setGravity(int gravity){
257 | this.GRAVITY = gravity;
258 | }
259 |
260 | /**
261 | * 设置小字显示
262 | * @param time
263 | */
264 | public void setSmallText(String text){
265 | this.mSmallText = text;
266 | update();
267 | }
268 |
269 | /**
270 | * 设置大字显示
271 | * @param time
272 | */
273 | public void setBigText(String text){
274 | this.mBigText = text;
275 | update();
276 | }
277 |
278 | /**
279 | * 设置字体颜色
280 | * @param resourceId
281 | */
282 | public void setTextColor(int resourceId){
283 | this.mTextColor = getResources().getColor(resourceId);
284 | update();
285 | }
286 |
287 | /**
288 | * 设置圆点颜色
289 | * @param resourceId
290 | */
291 | public void setPointColor(int resourceId){
292 | this.mPointColor = getResources().getColor(resourceId);
293 | update();
294 | }
295 |
296 | /**
297 | * 设置大字尺寸
298 | * @param size
299 | */
300 | public void setBigTextSize(float size){
301 | this.mBigTextSize = size;
302 | update();
303 | }
304 |
305 | /**
306 | * 设置小字尺寸
307 | * @param size
308 | */
309 | public void setSmallTextSize(float size){
310 | this.mSmallTextSize = size;
311 | update();
312 | }
313 |
314 | /**
315 | * 设置圆圆半径
316 | * @param size
317 | */
318 | public void setPointRadius(float size){
319 | this.mCircleRadius = size;
320 | update();
321 | }
322 |
323 | private void update(){
324 | this.invalidate();
325 | }
326 | }
327 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.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 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
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 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
--------------------------------------------------------------------------------