├── Sample
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── drawable-xxxhdpi
│ │ │ └── miao.png
│ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── strings.xml
│ │ │ ├── dimens.xml
│ │ │ ├── colors.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ └── layout
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_see_logcat.xml
│ │ │ ├── activity_test_custom_view.xml
│ │ │ ├── item_main.xml
│ │ │ └── activity_test_rorate3d_animation.xml
│ │ ├── java
│ │ └── com
│ │ │ └── gcssloop
│ │ │ └── test
│ │ │ ├── base
│ │ │ └── BaseActivity.java
│ │ │ ├── viewsupport
│ │ │ ├── TestCanvasAidUtilsActivity.java
│ │ │ ├── TestCustomViewActivity.java
│ │ │ ├── TestMorionEventHelperActivity.java
│ │ │ ├── TestApiHelperActivity.java
│ │ │ └── TestRotate3dAnimationActivity.java
│ │ │ ├── date
│ │ │ └── MainMenu.java
│ │ │ ├── MainActivity.java
│ │ │ ├── adapter
│ │ │ ├── ViewHolder.java
│ │ │ └── CommonAdapter.java
│ │ │ └── utils
│ │ │ └── CrashHandler.java
│ │ └── AndroidManifest.xml
├── proguard-rules.pro
├── build.gradle
└── Sample.iml
├── Library
├── .gitignore
├── proguard-rules.pro
├── src
│ └── main
│ │ ├── res
│ │ └── values
│ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── gcssloop
│ │ └── view
│ │ ├── utils
│ │ ├── CanvasUtils.java
│ │ ├── DensityUtils.java
│ │ ├── MathUtils.java
│ │ ├── ViewUtils.java
│ │ └── CanvasAidUtils.java
│ │ ├── CustomView.java
│ │ ├── helper
│ │ ├── MotionEventHelper.java
│ │ └── ApiHelper.java
│ │ └── animation
│ │ └── Rotate3dAnimation.java
├── build.gradle
└── Library.iml
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
├── ViewSupport.iml
├── gradle.properties
├── gradlew.bat
├── README-EN.md
├── README.md
├── gradlew
└── LICENSE
/Sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/Library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GcsSloop/ViewSupport/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/Sample/src/main/res/drawable-xxxhdpi/miao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GcsSloop/ViewSupport/HEAD/Sample/src/main/res/drawable-xxxhdpi/miao.png
--------------------------------------------------------------------------------
/Sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GcsSloop/ViewSupport/HEAD/Sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GcsSloop/ViewSupport/HEAD/Sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GcsSloop/ViewSupport/HEAD/Sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GcsSloop/ViewSupport/HEAD/Sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GcsSloop/ViewSupport/HEAD/Sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 | /*/build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
--------------------------------------------------------------------------------
/Library/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/GcsSloop/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/Sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/GcsSloop/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | include ':Sample', ':Library'
21 |
--------------------------------------------------------------------------------
/Library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | Library
22 |
23 |
--------------------------------------------------------------------------------
/Sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | ViewSupport
22 |
23 |
--------------------------------------------------------------------------------
/Sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 | 16dp
23 | 16dp
24 |
25 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2016 GcsSloop
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | # Last modified 2016-12-03 22:55:54
17 | #
18 | #
19 |
20 | #Mon Oct 31 01:52:12 CST 2016
21 | distributionBase=GRADLE_USER_HOME
22 | distributionPath=wrapper/dists
23 | zipStoreBase=GRADLE_USER_HOME
24 | zipStorePath=wrapper/dists
25 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
26 |
--------------------------------------------------------------------------------
/Sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 | #F99E7F
23 | #DF9C81
24 | #FF4081
25 |
26 |
--------------------------------------------------------------------------------
/ViewSupport.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
24 | 64dp
25 |
26 |
--------------------------------------------------------------------------------
/Sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
28 |
29 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Sample/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | apply plugin: 'com.android.application'
21 |
22 | android {
23 | compileSdkVersion 23
24 | buildToolsVersion "23.0.3"
25 |
26 | defaultConfig {
27 | applicationId "com.gcssloop.viewsupport"
28 | minSdkVersion 9
29 | targetSdkVersion 23
30 | versionCode 1
31 | versionName "1.0"
32 | }
33 | buildTypes {
34 | release {
35 | minifyEnabled false
36 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
37 | }
38 | }
39 | }
40 |
41 | dependencies {
42 | compile fileTree(include: ['*.jar'], dir: 'libs')
43 | testCompile 'junit:junit:4.12'
44 | compile 'com.android.support:appcompat-v7:23.4.0'
45 | compile project(':Library')
46 | compile 'com.android.support:cardview-v7:23.4.0'
47 | }
48 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2016 GcsSloop
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | # Last modified 2016-12-03 22:55:55
17 | #
18 | #
19 |
20 | # Project-wide Gradle settings.
21 |
22 | # IDE (e.g. Android Studio) users:
23 | # Gradle settings configured through the IDE *will override*
24 | # any settings specified in this file.
25 |
26 | # For more details on how to configure your build environment visit
27 | # http://www.gradle.org/docs/current/userguide/build_environment.html
28 |
29 | # Specifies the JVM arguments used for the daemon process.
30 | # The setting is particularly useful for tweaking memory settings.
31 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
32 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
33 |
34 | # When configured, Gradle will run in incubating parallel mode.
35 | # This option should only be used with decoupled projects. More details, visit
36 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
37 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/utils/CanvasUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view.utils;
21 |
22 | import android.graphics.Canvas;
23 | import android.graphics.Paint;
24 | import android.graphics.Point;
25 | import android.graphics.PointF;
26 |
27 | public class CanvasUtils {
28 |
29 |
30 | private CanvasUtils() {
31 | }
32 |
33 | /**
34 | * Draw a straight line through the points.
35 | */
36 | public static void drawLine(Point p1, Point p2, Canvas canvas, Paint paint) {
37 | canvas.save();
38 | canvas.drawLine(p1.x, p1.y, p2.x, p2.y, paint);
39 | canvas.restore();
40 | }
41 |
42 | /**
43 | * Draw a straight line through the points
44 | */
45 | public static void drawLine(PointF p1, PointF p2, Canvas canvas, Paint paint) {
46 | canvas.save();
47 | canvas.drawLine(p1.x, p1.y, p2.x, p2.y, paint);
48 | canvas.restore();
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:54
17 | *
18 | */
19 |
20 | package com.gcssloop.test.base;
21 |
22 | import android.os.Bundle;
23 | import android.support.annotation.Nullable;
24 | import android.support.v7.app.AppCompatActivity;
25 | import android.view.MenuItem;
26 |
27 |
28 | public class BaseActivity extends AppCompatActivity {
29 |
30 | @Override
31 | protected void onCreate(@Nullable Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | // Title显示当前类名
34 | this.setTitle(this.getClass().getSimpleName());
35 | }
36 |
37 | // 监听重载 ActionBar 左上角按钮事件。
38 | @Override
39 | public boolean onOptionsItemSelected(MenuItem item)
40 | {
41 | // TODO Auto-generated method stub
42 | if(item.getItemId() == android.R.id.home) {
43 | finish();
44 | return true;
45 | }
46 | return super.onOptionsItemSelected(item);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Sample/src/main/res/layout/activity_see_logcat.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
32 |
33 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Sample/src/main/res/layout/activity_test_custom_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
31 |
32 |
39 |
40 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Sample/src/main/res/layout/item_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
29 |
30 |
39 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/viewsupport/TestCanvasAidUtilsActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-05 23:34:36
17 | *
18 | */
19 |
20 | package com.gcssloop.test.viewsupport;
21 |
22 | import android.content.Context;
23 | import android.graphics.Canvas;
24 | import android.os.Bundle;
25 | import android.support.annotation.Nullable;
26 |
27 | import com.gcssloop.test.base.BaseActivity;
28 | import com.gcssloop.view.CustomView;
29 | import com.gcssloop.view.utils.CanvasAidUtils;
30 |
31 | public class TestCanvasAidUtilsActivity extends BaseActivity {
32 |
33 | @Override
34 | protected void onCreate(@Nullable Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(new TestCanvasAidUtilsView(this));
37 | }
38 | }
39 |
40 | class TestCanvasAidUtilsView extends CustomView {
41 |
42 | public TestCanvasAidUtilsView(Context context) {
43 | super(context);
44 |
45 | }
46 |
47 | @Override
48 | protected void onDraw(Canvas canvas) {
49 | super.onDraw(canvas);
50 |
51 | // 平移坐标系
52 | canvas.translate(mViewWidth/2, mViewHeight/2);
53 |
54 | // 重置坐标轴长度
55 | CanvasAidUtils.set2DAxisLength(mViewWidth/2*0.8f, mViewHeight/2*0.8f);
56 |
57 | // 绘制辅助坐标系
58 | CanvasAidUtils.draw2DCoordinateSpace(canvas);
59 | }
60 | }
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/viewsupport/TestCustomViewActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.test.viewsupport;
21 |
22 | import android.content.Context;
23 | import android.graphics.Canvas;
24 | import android.graphics.Color;
25 | import android.graphics.Paint;
26 | import android.os.Bundle;
27 |
28 | import com.gcssloop.test.base.BaseActivity;
29 | import com.gcssloop.view.CustomView;
30 |
31 | public class TestCustomViewActivity extends BaseActivity {
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(new MyView(this));
37 | }
38 |
39 | public class MyView extends CustomView{
40 |
41 | public MyView(Context context) {
42 | super(context);
43 | mDeafultPaint.setColor(Color.GRAY); // 获得一个默认的画笔
44 | mDeafultPaint.setTextSize(42);
45 | mDeafultPaint.setTextAlign(Paint.Align.CENTER);
46 | }
47 |
48 | @Override
49 | protected void onDraw(Canvas canvas) {
50 | canvas.translate(mViewWidth/2,mViewHeight/2); // 获得视图宽高
51 |
52 | canvas.drawCircle(0, -100, 100, mDeafultPaint);
53 | canvas.drawText("用默认画笔绘制一个圆", 0, 60, mDeafultPaint);
54 | }
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/date/MainMenu.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:54
17 | *
18 | */
19 |
20 | package com.gcssloop.test.date;
21 |
22 | import com.gcssloop.test.viewsupport.TestApiHelperActivity;
23 | import com.gcssloop.test.viewsupport.TestCanvasAidUtilsActivity;
24 | import com.gcssloop.test.viewsupport.TestCustomViewActivity;
25 | import com.gcssloop.test.viewsupport.TestMorionEventHelperActivity;
26 | import com.gcssloop.test.viewsupport.TestRotate3dAnimationActivity;
27 |
28 | import java.util.ArrayList;
29 | import java.util.List;
30 |
31 | public class MainMenu {
32 | public static List menu = new ArrayList();
33 |
34 | static{
35 | menu.add(new MenuEntity("CustomView测试", TestCustomViewActivity.class)) ;
36 | menu.add(new MenuEntity("Rotate3dAnimation测试", TestRotate3dAnimationActivity.class)) ;
37 | menu.add(new MenuEntity("ApiHelper测试", TestApiHelperActivity.class)) ;
38 | menu.add(new MenuEntity("MotionEventHelper测试", TestMorionEventHelperActivity.class)) ;
39 | menu.add(new MenuEntity("CanvasAidUtils测试", TestCanvasAidUtilsActivity.class)) ;
40 | }
41 |
42 | public static class MenuEntity{
43 | public String info;
44 | public Class> goClass;
45 | public MenuEntity(String info,Class> goClass) {
46 | this.info=info;
47 | this.goClass=goClass;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/viewsupport/TestMorionEventHelperActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-05 18:44:07
17 | *
18 | */
19 |
20 | package com.gcssloop.test.viewsupport;
21 |
22 | import android.graphics.Matrix;
23 | import android.os.Bundle;
24 | import android.support.annotation.Nullable;
25 | import android.util.Log;
26 | import android.view.MotionEvent;
27 | import android.widget.TextView;
28 |
29 | import com.gcssloop.test.base.BaseActivity;
30 | import com.gcssloop.view.helper.MotionEventHelper;
31 | import com.gcssloop.viewsupporttest.R;
32 |
33 | public class TestMorionEventHelperActivity extends BaseActivity {
34 | private static final String TAG = "TestMorionEventHelper";
35 | Matrix mMatrix;
36 |
37 | @Override
38 | protected void onCreate(@Nullable Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_see_logcat);
41 | TextView text = (TextView) findViewById(R.id.custom_view_text);
42 | text.append("\n在屏幕上触摸,查看坐标变化。\nx,y坐标均增加100");
43 |
44 | mMatrix = new Matrix();
45 | mMatrix.postTranslate(100,100);
46 | }
47 |
48 | @Override
49 | public boolean onTouchEvent(MotionEvent event) {
50 | Log.i(TAG, "转换前 > "+event.getX()+" : "+event.getY());
51 | MotionEvent e = MotionEventHelper.transformEvent(event, mMatrix);
52 | Log.i(TAG, "转换后 > "+e.getX()+" : "+e.getY());
53 | Log.i(TAG, "-------------------------");
54 | return true;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/CustomView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view;
21 |
22 | import android.content.Context;
23 | import android.graphics.Paint;
24 | import android.text.TextPaint;
25 | import android.util.AttributeSet;
26 | import android.view.View;
27 |
28 | public class CustomView extends View {
29 |
30 | /**
31 | * the context of current view
32 | */
33 | protected Context mCurrentContext;
34 |
35 | /**
36 | * the width of current view.
37 | */
38 | protected int mViewWidth;
39 |
40 | /**
41 | * the height of current view.
42 | */
43 | protected int mViewHeight;
44 |
45 | /**
46 | * default Paint.
47 | */
48 | protected Paint mDeafultPaint = new Paint();
49 |
50 | /**
51 | * default TextPaint
52 | */
53 | protected TextPaint mDefaultTextPaint = new TextPaint();
54 |
55 |
56 | public CustomView(Context context) {
57 | this(context, null);
58 | }
59 |
60 | public CustomView(Context context, AttributeSet attrs) {
61 | this(context, attrs, 0);
62 | }
63 |
64 | public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
65 | super(context, attrs, defStyleAttr);
66 | this.mCurrentContext = context;
67 | }
68 |
69 |
70 | @Override
71 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
72 | super.onSizeChanged(w, h, oldw, oldh);
73 | mViewWidth = w;
74 | mViewHeight = h;
75 | }
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/Library/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | apply plugin: 'com.android.library'
21 | apply plugin: 'com.github.dcendents.android-maven' // ADD THIS
22 |
23 | group='com.github.GcsSloop'
24 |
25 | android {
26 | compileSdkVersion 23
27 | buildToolsVersion "23.0.3"
28 |
29 | defaultConfig {
30 | minSdkVersion 9
31 | targetSdkVersion 23
32 | versionCode 1
33 | versionName "1.0"
34 | }
35 | buildTypes {
36 | release {
37 | minifyEnabled false
38 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
39 | }
40 | }
41 | }
42 |
43 | // encoding
44 | tasks.withType(JavaCompile) {
45 | options.encoding = "UTF-8"
46 | }
47 |
48 | dependencies {
49 | compile fileTree(dir: 'libs', include: ['*.jar'])
50 | testCompile 'junit:junit:4.12'
51 | compile 'com.android.support:appcompat-v7:23.4.0'
52 | }
53 |
54 | // build a jar with source files
55 | task sourcesJar(type: Jar) {
56 | from android.sourceSets.main.java.srcDirs
57 | classifier = 'sources'
58 | }
59 |
60 | task javadoc(type: Javadoc) {
61 | failOnError false
62 | source = android.sourceSets.main.java.sourceFiles
63 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
64 | classpath += configurations.compile
65 | }
66 |
67 | // build a jar with javadoc
68 | task javadocJar(type: Jar, dependsOn: javadoc) {
69 | classifier = 'javadoc'
70 | from javadoc.destinationDir
71 | }
72 |
73 | artifacts {
74 | archives sourcesJar
75 | archives javadocJar
76 | }
77 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/viewsupport/TestApiHelperActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-04 03:39:58
17 | *
18 | */
19 |
20 | package com.gcssloop.test.viewsupport;
21 |
22 | import android.os.Bundle;
23 | import android.support.annotation.Nullable;
24 | import android.util.Log;
25 |
26 | import com.gcssloop.test.base.BaseActivity;
27 | import com.gcssloop.view.helper.ApiHelper;
28 | import com.gcssloop.viewsupporttest.R;
29 |
30 | public class TestApiHelperActivity extends BaseActivity{
31 | private static final String TAG = "TestApiHelper";
32 |
33 | @Override
34 | protected void onCreate(@Nullable Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_see_logcat);
37 |
38 | Class testClass = com.gcssloop.test.viewsupport.MyClass.class;
39 |
40 | Log.i(TAG, "-----------------------");
41 |
42 | // 测试某个类是否包含该字段
43 | Log.i(TAG, "hasField - (T): "+ApiHelper.hasField(testClass, "mSloop"));
44 | Log.i(TAG, "hasField - (F): "+ApiHelper.hasField(testClass, "mField"));
45 |
46 | Log.i(TAG, "-----------------------");
47 |
48 | // 测试某个类是否包含该方法
49 | Log.i(TAG, "hasMethod - (T): "+ApiHelper.hasMethod("com.gcssloop.test.viewsupport.MyClass", "MyMethod"));
50 | Log.i(TAG, "hasMethod - (T): "+ApiHelper.hasMethod(testClass, "MyMethod"));
51 | Log.i(TAG, "hasMethod - (T): "+ApiHelper.hasMethod(testClass, "MyMethod", String.class));
52 | Log.i(TAG, "hasMethod - (F): "+ApiHelper.hasMethod(testClass, "MyMethod", int.class));
53 |
54 | }
55 | }
56 |
57 | /**
58 | * 一个被测试的类
59 | */
60 | class MyClass {
61 | int mSloop = 8;
62 |
63 |
64 | int MyMethod(){
65 | return 0;
66 | }
67 |
68 | int MyMethod(String haha){
69 | return 0;
70 | }
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/MainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.test;
21 |
22 | import android.annotation.TargetApi;
23 | import android.content.Intent;
24 | import android.os.Build;
25 | import android.os.Bundle;
26 | import android.view.View;
27 | import android.widget.AdapterView;
28 | import android.widget.ListView;
29 | import android.widget.TextView;
30 |
31 | import com.gcssloop.test.adapter.CommonAdapter;
32 | import com.gcssloop.test.adapter.ViewHolder;
33 | import com.gcssloop.test.base.BaseActivity;
34 | import com.gcssloop.test.date.MainMenu;
35 | import com.gcssloop.test.utils.CrashHandler;
36 | import com.gcssloop.viewsupporttest.R;
37 |
38 | public class MainActivity extends BaseActivity {
39 | private static final String TAG = "MainActivity";
40 |
41 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | super.onCreate(savedInstanceState);
45 | setContentView(R.layout.activity_main);
46 | CrashHandler.getInstance().init(this.getApplicationContext());
47 |
48 | ListView listView = (ListView) findViewById(R.id.main_list);
49 |
50 | assert listView != null;
51 | listView.setAdapter(new CommonAdapter(this, MainMenu.menu, R.layout.item_main) {
52 | @Override
53 | public void convert(int position, ViewHolder holder, MainMenu.MenuEntity bean) {
54 | TextView textView = holder.getView(R.id.item_main_text);
55 | textView.setText(bean.info);
56 | }
57 | });
58 |
59 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
60 | @Override
61 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
62 | startActivity(new Intent(MainActivity.this, MainMenu.menu.get(position).goClass));
63 | }
64 | });
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/adapter/ViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:54
17 | *
18 | */
19 |
20 | package com.gcssloop.test.adapter;
21 |
22 | import android.content.Context;
23 | import android.util.SparseArray;
24 | import android.view.LayoutInflater;
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | public class ViewHolder {
29 |
30 | private SparseArray mViews;
31 | private View mConvertView;
32 |
33 | private ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
34 | this.mViews = new SparseArray();
35 | mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
36 | mConvertView.setTag(this); //setTag
37 | }
38 |
39 | /**
40 | * 获取ViewHolder的实例
41 | *
42 | * @param context 上下文
43 | * @param convertView 布局
44 | * @param parent 父布局
45 | * @param layoutId 布局ID
46 | * @param position 位置
47 | * @return ViewHolder实例
48 | */
49 | public static ViewHolder getInstance(Context context, View convertView, ViewGroup parent, int layoutId, int
50 | position) {
51 | if (convertView == null) {
52 | return new ViewHolder(context, parent, layoutId, position);
53 | } else {
54 | return (ViewHolder) convertView.getTag();
55 | }
56 | }
57 |
58 | /**
59 | * 通过View的id来获取子View
60 | *
61 | * @param resId view的id
62 | * @param 泛型
63 | * @return 子View
64 | */
65 | public T getView(int resId) {
66 | View view = mViews.get(resId);
67 |
68 | //如果该View没有缓存过,则查找View并缓存
69 | if (view == null) {
70 | view = mConvertView.findViewById(resId);
71 | mViews.put(resId, view);
72 | }
73 |
74 | return (T) view;
75 | }
76 |
77 | /**
78 | * 获取布局View
79 | *
80 | * @return 布局View
81 | */
82 | public View getConvertView() {
83 | return mConvertView;
84 | }
85 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/adapter/CommonAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:54
17 | *
18 | */
19 |
20 | package com.gcssloop.test.adapter;
21 |
22 | import android.content.Context;
23 | import android.support.annotation.NonNull;
24 | import android.view.LayoutInflater;
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 | import android.widget.BaseAdapter;
28 |
29 | import java.util.ArrayList;
30 | import java.util.List;
31 |
32 | public abstract class CommonAdapter extends BaseAdapter {
33 |
34 | private LayoutInflater mInflater;
35 | private Context mContext;
36 | private List mDatas = new ArrayList<>();
37 | private int mLayoutId;
38 |
39 | /**
40 | * @param context 上下文
41 | * @param datas 数据集
42 | * @param layoutId 布局ID
43 | */
44 | public CommonAdapter(@NonNull Context context, List datas, @NonNull int layoutId) {
45 | mInflater = LayoutInflater.from(context);
46 | this.mContext = context;
47 | this.mLayoutId = layoutId;
48 | if(datas!=null){
49 | this.mDatas = datas;
50 | }
51 | }
52 |
53 | public void addDatas(List datas){
54 | this.mDatas.addAll(datas);
55 | notifyDataSetChanged();
56 | }
57 |
58 | public void clearDatas(){
59 | this.mDatas.clear();
60 | notifyDataSetChanged();
61 | }
62 |
63 | public T getDataById(int position){
64 | return mDatas.get(position);
65 | }
66 |
67 | @Override
68 | public int getCount() {
69 | return mDatas.size();
70 | }
71 |
72 | @Override
73 | public T getItem(int position) {
74 | return mDatas.get(position);
75 | }
76 |
77 | @Override
78 | public long getItemId(int position) {
79 | return position;
80 | }
81 |
82 | @Override
83 | public View getView(int position, View convertView, ViewGroup parent) {
84 | //实例化一个ViewHolder
85 | ViewHolder holder = ViewHolder.getInstance(mContext, convertView, parent, mLayoutId, position);
86 | //需要自定义的部分
87 | convert(position, holder, getItem(position));
88 |
89 | return holder.getConvertView();
90 | }
91 |
92 | /**
93 | * 需要处理的部分,在这里给View设置值
94 | *
95 | * @param holder ViewHolder
96 | * @param bean 数据集
97 | */
98 | public abstract void convert(int position, ViewHolder holder, T bean);
99 | }
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/utils/DensityUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view.utils;
21 |
22 | import android.content.Context;
23 |
24 | public class DensityUtils {
25 |
26 | public DensityUtils() {
27 | }
28 |
29 | /**
30 | * convert the dp to px depend on the device density.
31 | *
32 | * @param context the context
33 | * @param dpValue a value of dp
34 | * @return the result of px
35 | */
36 | public static int dip2px(Context context, float dpValue) {
37 | return (int) (dpValue * getDensity(context) + 0.5f);
38 | }
39 |
40 | /**
41 | * convert the px to dp depend on the device density.
42 | *
43 | * @param context the context
44 | * @param pxValue a value of px
45 | * @return the result of dp
46 | */
47 | public static int px2dip(Context context, float pxValue) {
48 | return (int) (pxValue / getDensity(context) + 0.5f);
49 | }
50 |
51 | /**
52 | * convert the sp to px depend on the device scaledDensity.
53 | *
54 | * @param context the context
55 | * @param spValue a value of sp
56 | * @return the result of px
57 | */
58 | public static int sp2px(Context context, float spValue) {
59 | return (int) (spValue * getFontDensity(context) + 0.5);
60 | }
61 |
62 | /**
63 | * convert the px to sp depend on the device scaledDensity.
64 | *
65 | * @param context the context
66 | * @param pxValue a value of px
67 | * @return the result of sp
68 | */
69 | public static int px2sp(Context context, float pxValue) {
70 | return (int) (pxValue / getFontDensity(context) + 0.5);
71 | }
72 |
73 | /**
74 | * get the density of device screen.
75 | *
76 | * @param context the context
77 | * @return the screen density
78 | */
79 | public static float getDensity(Context context) {
80 | return context.getResources().getDisplayMetrics().density;
81 | }
82 |
83 | /**
84 | * get the scale density of device screen.
85 | * usually this value is the same as density.
86 | * but it can adjust by user.
87 | *
88 | * @param context the context
89 | * @return the screen scale density.
90 | */
91 | public static float getFontDensity(Context context) {
92 | return context.getResources().getDisplayMetrics().scaledDensity;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/utils/MathUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view.utils;
21 |
22 | import android.graphics.Point;
23 | import android.graphics.PointF;
24 |
25 | public class MathUtils {
26 |
27 | public MathUtils() {
28 | }
29 |
30 | /**
31 | * Get the distance between two points.
32 | *
33 | * @param A Point A
34 | * @param B Point B
35 | * @return the distance between point A and point B.
36 | */
37 | public static int getDistance(PointF A, PointF B) {
38 | return (int) Math.sqrt(Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2));
39 | }
40 |
41 | /**
42 | * Get the distance between two points.
43 | */
44 | public static int getDistance(float x1, float y1, float x2, float y2) {
45 | return (int) Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
46 | }
47 |
48 | /**
49 | * Get the coordinates of a point on the line by cut length.
50 | *
51 | * @param A Point A
52 | * @param B Point B
53 | * @param cutLength cut length
54 | * @return the point.
55 | */
56 | public static Point getPointByCutLength(Point A, Point B, int cutLength) {
57 | float radian = getRadian(A, B);
58 | return new Point(A.x + (int) (cutLength * Math.cos(radian)), A.y + (int) (cutLength * Math.sin(radian)));
59 | }
60 |
61 | /**
62 | * Get the radian between current line(determined by point A and B) and horizontal line.
63 | *
64 | * @param A point A
65 | * @param B point B
66 | * @return the radian
67 | */
68 | public static float getRadian(Point A, Point B) {
69 | float lenA = B.x - A.x;
70 | float lenB = B.y - A.y;
71 | float lenC = (float) Math.sqrt(lenA * lenA + lenB * lenB);
72 | float radian = (float) Math.acos(lenA / lenC);
73 | radian = radian * (B.y < A.y ? -1 : 1);
74 | return radian;
75 | }
76 |
77 |
78 | /**
79 | * angle to radian
80 | *
81 | * @param angle angle
82 | * @return radian
83 | */
84 | public static double angle2Radian(double angle) {
85 | return angle / 180 * Math.PI;
86 | }
87 |
88 | /**
89 | * radian to angle
90 | *
91 | * @param radian radian
92 | * @return angle
93 | */
94 | public static double radian2Angle(double radian) {
95 | return radian / Math.PI * 180;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/README-EN.md:
--------------------------------------------------------------------------------
1 | # ViewSupport
2 |
3 | [](https://www.apache.org/licenses/LICENSE-2.0)
4 | 
5 | [](https://jitpack.io/#GcsSloop/ViewSupport)
6 |
7 | ### Weibo: [@GcsSloop](http://weibo.com/GcsSloop)
8 |
9 | This is a library for View and CustomView,it has some tools can help you operate view or help you custom view easily.
10 |
11 | *****
12 |
13 | ## Tools list
14 |
15 | you can click the tools name to see the source.
16 |
17 | Utils | Summary
18 | ----------------|----------------------------------
19 | CanvasAidUtils | Canvas Aid util, you can use it draw a coordinate system to help you check the view position.
20 | DensityUtils | A utils of screen density. it can help you convert the different unit. *E.g: dp -> px ps->dp sp->px px->sp*
21 | MathUtils | A Math utils, It can help you make some common calculations. *E.g: Get the distance between two points; angle2Radian; radian2Angle and others*
22 | ViewUtils | Utils for view. it can help you measure view, if you want get the view size before it not measured. or you can use it set view margin on code.
23 |
24 |
25 |
26 | ## Get it
27 |
28 | #### Gradle:
29 |
30 | **Step 1. Add the JitPack repository to your build file**
31 |
32 | Add it in your root build.gradle at the end of repositories:
33 |
34 | ``` gradle
35 | allprojects {
36 | repositories {
37 | ...
38 | maven { url "https://jitpack.io" }
39 | }
40 | }
41 | ```
42 |
43 | **Step 2. Add the dependency**
44 |
45 | ``` gradle
46 | dependencies {
47 | compile 'com.github.GcsSloop:ViewSupport:v1.0.3'
48 | }
49 | ```
50 |
51 | #### Maven
52 |
53 | **Step 1. Add the JitPack repository to your build file**
54 |
55 | Add it in your root build.gradle at the end of repositories:
56 |
57 | ``` maven
58 |
59 |
60 | jitpack.io
61 | https://jitpack.io
62 |
63 |
64 | ```
65 |
66 | **Step 2. Add the dependency**
67 |
68 | ``` maven
69 |
70 | com.github.GcsSloop
71 | ViewSupport
72 | v1.0.2
73 |
74 | ```
75 |
76 | ## About Me
77 |
78 | ### Weibo: [@GcsSloop](http://weibo.com/GcsSloop)
79 |
80 |
81 |
82 | ## License
83 |
84 | ```
85 | Copyright (c) 2016 GcsSloop
86 |
87 | Licensed under the Apache License, Version 2.0 (the "License");
88 | you may not use this file except in compliance with the License.
89 | You may obtain a copy of the License at
90 |
91 | http://www.apache.org/licenses/LICENSE-2.0
92 |
93 | Unless required by applicable law or agreed to in writing, software
94 | distributed under the License is distributed on an "AS IS" BASIS,
95 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
96 | See the License for the specific language governing permissions and
97 | limitations under the License.
98 | ```
99 |
--------------------------------------------------------------------------------
/Sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
22 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
39 |
40 |
43 |
44 |
46 |
47 |
50 |
51 |
53 |
54 |
57 |
58 |
60 |
61 |
64 |
65 |
67 |
68 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/Sample/src/main/res/layout/activity_test_rorate3d_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
28 |
29 |
37 |
38 |
44 |
52 |
59 |
66 |
67 |
72 |
73 |
74 |
79 |
80 |
87 |
88 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/viewsupport/TestRotate3dAnimationActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.test.viewsupport;
21 |
22 | import android.os.Bundle;
23 | import android.util.Log;
24 | import android.view.View;
25 | import android.view.animation.LinearInterpolator;
26 | import android.widget.Button;
27 | import android.widget.RadioGroup;
28 |
29 | import com.gcssloop.test.base.BaseActivity;
30 | import com.gcssloop.view.animation.Rotate3dAnimation;
31 | import com.gcssloop.viewsupporttest.R;
32 |
33 | public class TestRotate3dAnimationActivity extends BaseActivity {
34 | private static final String TAG = "TestRotate3dAnimation";
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 | setContentView(R.layout.activity_test_rorate3d_animation);
40 |
41 | final View view = findViewById(R.id.card);
42 |
43 | final int[] tempAxis = {1};
44 | RadioGroup group = (RadioGroup) findViewById(R.id.group);
45 | assert group != null;
46 | group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
47 | @Override
48 | public void onCheckedChanged(RadioGroup group, int checkedId) {
49 | switch (group.getCheckedRadioButtonId()) {
50 | case R.id.axis_x: tempAxis[0] =1; break;
51 | case R.id.axis_y: tempAxis[0] =2; break;
52 | case R.id.axis_z: tempAxis[0] =3; break;
53 | }
54 | }
55 | });
56 |
57 | final Button start = (Button) findViewById(R.id.btn_start);
58 | assert start != null;
59 | start.setOnClickListener(new View.OnClickListener() {
60 | @Override
61 | public void onClick(View v) {
62 | startTestRotate(view, tempAxis[0]);
63 | Log.e(TAG, "开始旋转 - "+tempAxis[0]);
64 | }
65 | });
66 | }
67 |
68 | private void startTestRotate(View view, int axis) {
69 | float start = 0f;
70 | float end = 360f;
71 |
72 | // 计算中心点(这里是使用view的中心作为旋转的中心点)
73 | final float centerX = view.getWidth() / 2.0f;
74 | final float centerY = view.getHeight() / 2.0f;
75 |
76 | //括号内参数分别为(上下文,开始角度,结束角度,x轴中心点,y轴中心点,深度,是否扭曲)
77 | final Rotate3dAnimation rotation = new Rotate3dAnimation(this, start, end, centerX, centerY, 0f, true);
78 |
79 | rotation.setAxis(axis); // 设置坐标系
80 | rotation.setDuration(3000); // 设置动画时长
81 | rotation.setFillAfter(true); // 保持旋转后效果
82 | rotation.setInterpolator(new LinearInterpolator()); // 设置插值器
83 |
84 | view.startAnimation(rotation); //开始动画
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Sample/src/main/java/com/gcssloop/test/utils/CrashHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:54
17 | *
18 | */
19 |
20 | package com.gcssloop.test.utils;
21 |
22 | import android.content.Context;
23 | import android.os.Looper;
24 | import android.util.Log;
25 | import android.widget.Toast;
26 |
27 | import java.text.DateFormat;
28 | import java.text.SimpleDateFormat;
29 | import java.util.Locale;
30 |
31 | public class CrashHandler implements Thread.UncaughtExceptionHandler {
32 | private static final String TAG = CrashHandler.class.getSimpleName();
33 |
34 | private static CrashHandler instance; // 单例模式
35 |
36 | //private OnBeforeHandleExceptionListener mListener;
37 |
38 | private Context context; // 程序Context对象
39 | private Thread.UncaughtExceptionHandler defalutHandler; // 系统默认的UncaughtException处理类
40 | private DateFormat formatter = new SimpleDateFormat(
41 | "yyyy-MM-dd_HH-mm-ss.SSS", Locale.CHINA);
42 |
43 | private CrashHandler() {
44 |
45 | }
46 |
47 | /**
48 | * 获取CrashHandler实例
49 | *
50 | * @return CrashHandler
51 | */
52 | public static CrashHandler getInstance() {
53 | if (instance == null) {
54 | synchronized (CrashHandler.class) {
55 | if (instance == null) {
56 | instance = new CrashHandler();
57 | }
58 | }
59 | }
60 |
61 | return instance;
62 | }
63 |
64 | /**
65 | * 异常处理初始化
66 | *
67 | * @param context
68 | */
69 | public void init(Context context) {
70 | this.context = context;
71 | // 获取系统默认的UncaughtException处理器
72 | defalutHandler = Thread.getDefaultUncaughtExceptionHandler();
73 | // 设置该CrashHandler为程序的默认处理器
74 | Thread.setDefaultUncaughtExceptionHandler(this);
75 | }
76 |
77 | /**
78 | * 当UncaughtException发生时会转入该函数来处理
79 | */
80 | @Override
81 | public void uncaughtException(Thread thread, Throwable ex) {
82 | //异常发生时,先给蓝牙服务端发送OK命令
83 | //if (mListener != null) {
84 | // mListener.onBeforeHandleException();
85 | // }
86 |
87 | // 自定义错误处理
88 | boolean res = handleException(ex);
89 | if (!res && defalutHandler != null) {
90 | // 如果用户没有处理则让系统默认的异常处理器来处理
91 | defalutHandler.uncaughtException(thread, ex);
92 |
93 | } else {
94 | try {
95 | Thread.sleep(3000);
96 | } catch (InterruptedException e) {
97 | Log.e(TAG, "error : ", e);
98 | }
99 | // 退出程序
100 | android.os.Process.killProcess(android.os.Process.myPid());
101 | System.exit(1);
102 | }
103 | }
104 |
105 | /**
106 | * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
107 | *
108 | * @param ex
109 | * @return true:如果处理了该异常信息;否则返回false.
110 | */
111 | private boolean handleException(final Throwable ex) {
112 | if (ex == null) {
113 | return false;
114 | }
115 |
116 | new Thread() {
117 |
118 | @Override
119 | public void run() {
120 | Looper.prepare();
121 |
122 | ex.printStackTrace();
123 | String err = "[" + ex.getMessage() + "]";
124 | Toast.makeText(context, "程序出现异常." + err, Toast.LENGTH_LONG)
125 | .show();
126 |
127 | Looper.loop();
128 | }
129 |
130 | }.start();
131 |
132 | // 收集设备参数信息 \日志信息
133 | //String errInfo = collectDeviceInfo(context, ex);
134 | // 保存日志文件
135 | //saveCrashInfo2File(errInfo);
136 | return true; }
137 | }
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/utils/ViewUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view.utils;
21 |
22 | import android.view.View;
23 | import android.view.ViewGroup;
24 |
25 | public class ViewUtils {
26 |
27 | public ViewUtils() {
28 | }
29 |
30 | /*The method about measure view****************************************************************/
31 |
32 | /**
33 | * measure view
34 | * if you want get view size before the view measured, you should call this method.
35 | * E.g you want gei the view size on constructor method
36 | *
37 | * The width and height is a value or type, it can used like this.
38 | * E.g: measureView(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
39 | *
40 | * @param view The view that will be measured
41 | * @param width the default width
42 | * @param height the default height
43 | */
44 | public static void measureView(View view, int width, int height) {
45 | ViewGroup.LayoutParams params = view.getLayoutParams();
46 | if (params == null) {
47 | params = new ViewGroup.LayoutParams(width, height);
48 | }
49 | int mWidth = ViewGroup.getChildMeasureSpec(0, 0, params.width);
50 |
51 | int mHeight;
52 | int tempHeight = params.height;
53 | if (tempHeight > 0) {
54 | mHeight = View.MeasureSpec.makeMeasureSpec(tempHeight, View.MeasureSpec.EXACTLY);
55 | } else {
56 | mHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
57 | }
58 | view.measure(mWidth, mHeight);
59 | }
60 |
61 | /*The method about view margin*****************************************************************/
62 |
63 | /**
64 | * set margin left
65 | *
66 | * @param view the view
67 | * @param left value of margin left
68 | */
69 | public static void setMarginLeft(View view, int left) {
70 | setMargins(view, left, 0, 0, 0);
71 | }
72 |
73 | /**
74 | * set margin top
75 | *
76 | * @param view the view
77 | * @param top value of margin top
78 | */
79 | public static void setMarginTop(View view, int top) {
80 | setMargins(view, 0, top, 0, 0);
81 | }
82 |
83 | /**
84 | * set margin right
85 | *
86 | * @param view the view
87 | * @param right value of margin right
88 | */
89 | public static void setMarginRight(View view, int right) {
90 | setMargins(view, 0, 0, right, 0);
91 | }
92 |
93 | /**
94 | * set margin bottom
95 | *
96 | * @param view the view
97 | * @param bottom value of margin bottom
98 | */
99 | public static void setMarginBottom(View view, int bottom) {
100 | setMargins(view, 0, 0, 0, bottom);
101 | }
102 |
103 | /**
104 | * set view margin
105 | *
106 | * @param view the view
107 | * @param left value of margin left
108 | * @param top value of margin top
109 | * @param right value of margin right
110 | * @param bottom value of margin bottom
111 | */
112 | public static void setMargins(View view, int left, int top, int right, int bottom) {
113 | if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
114 | ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
115 | p.setMargins(left, top, right, bottom);
116 | view.requestLayout(); //请求重绘
117 | }
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/helper/MotionEventHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view.helper;
21 |
22 | import android.view.MotionEvent;
23 |
24 | import android.annotation.TargetApi;
25 | import android.graphics.Matrix;
26 | import android.view.MotionEvent.PointerCoords;
27 |
28 | public final class MotionEventHelper {
29 | private MotionEventHelper() {}
30 |
31 | public static MotionEvent transformEvent(MotionEvent e, Matrix m) {
32 | // We try to use the new transform method if possible because it uses
33 | // less memory.
34 | if (ApiHelper.HAS_MOTION_EVENT_TRANSFORM) {
35 | return transformEventNew(e, m);
36 | } else {
37 | return transformEventOld(e, m);
38 | }
39 | }
40 |
41 | @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
42 | private static MotionEvent transformEventNew(MotionEvent e, Matrix m) {
43 | MotionEvent newEvent = MotionEvent.obtain(e);
44 | newEvent.transform(m);
45 | return newEvent;
46 | }
47 |
48 | // This is copied from Input.cpp in the android framework.
49 | private static MotionEvent transformEventOld(MotionEvent e, Matrix m) {
50 | long downTime = e.getDownTime();
51 | long eventTime = e.getEventTime();
52 | int action = e.getAction();
53 | int pointerCount = e.getPointerCount();
54 | int[] pointerIds = getPointerIds(e);
55 | PointerCoords[] pointerCoords = getPointerCoords(e);
56 | int metaState = e.getMetaState();
57 | float xPrecision = e.getXPrecision();
58 | float yPrecision = e.getYPrecision();
59 | int deviceId = e.getDeviceId();
60 | int edgeFlags = e.getEdgeFlags();
61 | int source = e.getSource();
62 | int flags = e.getFlags();
63 | // Copy the x and y coordinates into an array, map them, and copy back.
64 | float[] xy = new float[pointerCoords.length * 2];
65 | for (int i = 0; i < pointerCount;i++) {
66 | xy[2 * i] = pointerCoords[i].x;
67 | xy[2 * i + 1] = pointerCoords[i].y;
68 | }
69 | m.mapPoints(xy);
70 | for (int i = 0; i < pointerCount;i++) {
71 | pointerCoords[i].x = xy[2 * i];
72 | pointerCoords[i].y = xy[2 * i + 1];
73 | pointerCoords[i].orientation = transformAngle(
74 | m, pointerCoords[i].orientation);
75 | }
76 | MotionEvent n = MotionEvent.obtain(downTime, eventTime, action,
77 | pointerCount, pointerIds, pointerCoords, metaState, xPrecision,
78 | yPrecision, deviceId, edgeFlags, source, flags);
79 | return n;
80 | }
81 |
82 | private static int[] getPointerIds(MotionEvent e) {
83 | int n = e.getPointerCount();
84 | int[] r = new int[n];
85 | for (int i = 0; i < n; i++) {
86 | r[i] = e.getPointerId(i);
87 | }
88 | return r;
89 | }
90 |
91 | private static PointerCoords[] getPointerCoords(MotionEvent e) {
92 | int n = e.getPointerCount();
93 | PointerCoords[] r = new PointerCoords[n];
94 | for (int i = 0; i < n; i++) {
95 | r[i] = new PointerCoords();
96 | e.getPointerCoords(i, r[i]);
97 | }
98 | return r;
99 | }
100 |
101 | private static float transformAngle(Matrix m, float angleRadians) {
102 | // Construct and transform a vector oriented at the specified clockwise
103 | // angle from vertical. Coordinate system: down is increasing Y, right is
104 | // increasing X.
105 | float[] v = new float[2];
106 | v[0] = (float) Math.sin(angleRadians);
107 | v[1] = (float) Math.cos(angleRadians);
108 | m.mapVectors(v);
109 | // Derive the transformed vector's clockwise angle from vertical.
110 | float result = (float) Math.atan2(v[0], -v[1]);
111 | if (result < -Math.PI / 2) {
112 | result += Math.PI;
113 | } else if (result > Math.PI / 2) {
114 | result -= Math.PI;
115 | }
116 | return result;
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/animation/Rotate3dAnimation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view.animation;
21 |
22 | import android.content.Context;
23 | import android.graphics.Camera;
24 | import android.graphics.Matrix;
25 | import android.view.animation.Animation;
26 | import android.view.animation.Transformation;
27 |
28 | public class Rotate3dAnimation extends Animation {
29 | private final float mFromDegrees;
30 | private final float mToDegrees;
31 | private final float mCenterX;
32 | private final float mCenterY;
33 | private final float mDepthZ;
34 | private final boolean mReverse;
35 | private Camera mCamera;
36 | private float scale = 1;
37 |
38 | private int mAxis = 2; // 围绕旋转的轴,默认是y轴
39 | public static final int AXIS_X = 1;
40 | public static final int AXIS_Y = 2;
41 | public static final int AXIS_Z = 3;
42 |
43 | /**
44 | * 创建一个绕y轴旋转的3D动画效果,旋转过程中具有深度调节,可以指定旋转中心。
45 | *
46 | * @param context 上下文
47 | * @param fromDegrees 起始时角度
48 | * @param toDegrees 结束时角度
49 | * @param centerX 旋转中心x坐标
50 | * @param centerY 旋转中心y坐标
51 | * @param depthZ 最远到达的z轴坐标
52 | * @param reverse true 表示由从0到depthZ,false相反
53 | */
54 | public Rotate3dAnimation(Context context, float fromDegrees, float toDegrees,
55 | float centerX, float centerY, float depthZ, boolean reverse) {
56 | mFromDegrees = fromDegrees;
57 | mToDegrees = toDegrees;
58 | mCenterX = centerX;
59 | mCenterY = centerY;
60 | mDepthZ = depthZ;
61 | mReverse = reverse;
62 |
63 | //获取手机像素比 (即dp与px的比例
64 | scale = context.getResources().getDisplayMetrics().density;
65 | }
66 |
67 | /**
68 | * 创建一个绕y轴旋转的3D动画效果,旋转过程中具有深度调节,可以指定旋转中心。
69 | *
70 | * @param context 上下文
71 | * @param fromDegrees 起始时角度
72 | * @param toDegrees 结束时角度
73 | * @param centerX 旋转中心x坐标
74 | * @param centerY 旋转中心y坐标
75 | * @param depthZ 最远到达的z轴坐标
76 | * @param reverse true 表示由从0到depthZ,false相反
77 | * @param axis 围绕旋转的坐标轴
78 | */
79 | public Rotate3dAnimation(Context context, float fromDegrees, float toDegrees,
80 | float centerX, float centerY, float depthZ, boolean reverse, int axis) {
81 | this(context, fromDegrees, toDegrees, centerX, centerY, depthZ, reverse);
82 | setAxis(axis);
83 | }
84 |
85 | @Override
86 | public void initialize(int width, int height, int parentWidth, int parentHeight) {
87 | super.initialize(width, height, parentWidth, parentHeight);
88 | mCamera = new Camera();
89 | }
90 |
91 | @Override
92 | protected void applyTransformation(float interpolatedTime, Transformation t) {
93 | float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
94 | final Matrix matrix = t.getMatrix();
95 |
96 | mCamera.save();
97 |
98 | // 调节深度
99 | if (mReverse) {
100 | mCamera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
101 | } else {
102 | mCamera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
103 | }
104 |
105 | // 绕轴旋转
106 | switch (mAxis) {
107 | case 1:
108 | mCamera.rotateX(degrees);
109 | break;
110 | case 2:
111 | mCamera.rotateY(degrees);
112 | break;
113 | case 3:
114 | mCamera.rotateZ(degrees);
115 | break;
116 | }
117 |
118 | mCamera.getMatrix(matrix);
119 | mCamera.restore();
120 |
121 | // 修复失真
122 | float[] mValues = new float[9];
123 | matrix.getValues(mValues); //获取数值
124 | mValues[6] = mValues[6] / scale; //数值修正
125 | mValues[7] = mValues[7] / scale; //数值修正
126 | matrix.setValues(mValues); //重新赋值
127 |
128 | // 设置中心
129 | matrix.preTranslate(-mCenterX, -mCenterY);
130 | matrix.postTranslate(mCenterX, mCenterY);
131 | }
132 |
133 | /**
134 | * 设置围绕旋转的坐标轴
135 | *
136 | * @param axis
137 | */
138 | public void setAxis(int axis) {
139 | if (axis < 1 || axis > 3)
140 | return;
141 | mAxis = axis;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
ViewSupport
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 
10 |
11 | 该开源库的主要作用就是简化自定义View过程中的一些流程,让自定义View更简单,更方便,更高效,例如:
12 |
13 | * 继承 `CustomView` 以自动获取 View 大小以及默认画笔。
14 | * 使用 `CanvasAidUtils` 绘制当前坐标系以检查绘制的位置。
15 | * 使用 `MathUtils` 方便的进行角度弧度转换,计算距离。
16 |
17 | 除此之外,它还有更多的工具和辅助类来帮助你更方便的自定义View,更多信息请查看下面表格。
18 |
19 | 如果你对此有什么比较好的建议,欢迎提交 Issues 来告诉我。
20 |
21 | 对自定义View感兴趣的欢迎来 [我的博客](http://www.gcssloop.com/#blog) 查看相关文章。
22 |
23 | *****
24 |
25 | ## 工具列表
26 |
27 | >
28 | >**PS: 点击工具名称查看源码,点击Wiki查看简介。**
29 |
30 | | 工具 | Wiki | 简介 |
31 | | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
32 | | [CustomView](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/CustomView.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/CustomView) | 自定义View基类,帮助你节省部分代码 |
33 | | [CanvasAidUtils](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/utils/CanvasAidUtils.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/CanvasAidUtils) | Canvas辅助工具,你可以用它绘制坐标系来帮助你检查视图的位置,并在完成之后移除该坐标系。 |
34 | | [CanvasUtils](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/utils/CanvasUtils.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/CanvasUtils) | Canvas绘图工具,封装了一些Canvas没有提供的方法,目前只能用来画一条线。 |
35 | | [DensityUtils](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/utils/DensityUtils.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/DensityUtils) | 密度工具, 根据设备进行如下单位转换: sp -> px, px -> sp, dp -> px, px -> dp |
36 | | [MathUtils](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/utils/MathUtils.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/MathUtils) | 数学工具, 封装一些数学算法,例如: 获取两点之间的距离,获取线段上某一点的位置, 获取线段与水平线夹角 等 |
37 | | [ViewUtils](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/utils/ViewUtils.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/ViewUtils) | 视图工具, 封装了一些与视图相关等内容,如 手动测量视图大小, 为视图动态设置margin 等 |
38 | | [ApiHelper](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/helper/ApiHelper.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/ApiHelper) | 版本检查工具,里面定义了很多与版本相关的常量,并且开放了几个检查方法,检查一个类(class)是否拥有某个字段或者某个方法。 |
39 | | [MotionEventHelper](https://github.com/GcsSloop/ViewSupport/blob/master/Library/src/main/java/com/gcssloop/view/helper/MotionEventHelper.java) | [查看](https://github.com/GcsSloop/ViewSupport/wiki/MotionEventHelper) | MotionEvent 辅助类,帮助转换 MotionEvent 中的坐标系。 |
40 |
41 | ## 文档
42 |
43 | * [点击这里查看文档](https://jitpack.io/com/github/GcsSloop/ViewSupport/v1.2.2/javadoc/)
44 | * [点击这里查看Wiki](https://github.com/GcsSloop/ViewSupport/wiki)
45 | * [点击这里查看更新日志](https://github.com/GcsSloop/ViewSupport/releases)
46 |
47 | ## 示例
48 |
49 | [点击此处下载 Sample](https://github.com/GcsSloop/ViewSupport/raw/res/apk/Sample-ViewSupport.apk)
50 |
51 |
52 |
53 |
54 | ## 如何添加该开源库
55 |
56 | #### Gradle:
57 |
58 | **Step 1. 添加JitPack仓库**
59 |
60 | 在当前项目的根目录下的 `build.gradle` 文件中添加如下内容:
61 |
62 | ``` gradle
63 | allprojects {
64 | repositories {
65 | ...
66 | maven { url "https://jitpack.io" }
67 | }
68 | }
69 | ```
70 |
71 | **Step 2. 添加项目依赖**
72 |
73 | ``` gradle
74 | dependencies {
75 | compile 'com.github.GcsSloop:ViewSupport:v1.3.0'
76 | }
77 | ```
78 |
79 | ## About Me
80 |
81 | ### 微博: [@GcsSloop](http://weibo.com/GcsSloop)
82 |
83 |
84 |
85 | ## License
86 |
87 | ```
88 | Copyright (c) 2016 GcsSloop
89 |
90 | Licensed under the Apache License, Version 2.0 (the "License");
91 | you may not use this file except in compliance with the License.
92 | You may obtain a copy of the License at
93 |
94 | http://www.apache.org/licenses/LICENSE-2.0
95 |
96 | Unless required by applicable law or agreed to in writing, software
97 | distributed under the License is distributed on an "AS IS" BASIS,
98 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99 | See the License for the specific language governing permissions and
100 | limitations under the License.
101 | ```
102 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/utils/CanvasAidUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 |
20 | package com.gcssloop.view.utils;
21 |
22 | import android.graphics.Canvas;
23 | import android.graphics.Color;
24 | import android.graphics.Paint;
25 | import android.graphics.PointF;
26 |
27 | public class CanvasAidUtils {
28 |
29 | // field for 2D and 3D
30 | private static boolean isDrawAid = true;
31 | private static Paint mPaint;
32 | private static int mLineWidth = 5;
33 | private static int mLineColor = Color.GRAY;
34 |
35 | private static int Cap_Axis_Distance = 15;
36 | private static int Cap_Head_Distance = 30;
37 |
38 |
39 | // 2D
40 | private static float XAxisPosLen_2D = 500; // X axis positive length
41 | private static float XAxisNegLen_2D = 0; // X axis negative length
42 | private static float YAxisPosLen_2D = 700; // Y axis positive length
43 | private static float YAxisNegLen_2D = 0; // Y axis negative length
44 |
45 | private static PointF XHead_2D, XTail_2D, YHead_2D, YTail_2D;
46 | private static PointF XCap1_2D, XCap2_2D, YCap1_2D, YCap2_2D;
47 |
48 |
49 | // 3D
50 | private static float XAxisPosLen_3D = 400; // X axis positive length
51 | private static float XAxisNegLen_3D = 400; // X axis negative length
52 | private static float YAxisPosLen_3D = 500; // Y axis positive length
53 | private static float YAxisNegLen_3D = 500; // Y axis negative length
54 | private static float ZAxisPosLen_3D = 300; // Z axis positive length
55 | private static float ZAxisNegLen_3D = 400; // Z axis negative length
56 |
57 | private static PointF XHead_3D, XTail_3D, YHead_3D, YTail_3D, ZHead_3D, ZTail_3D;
58 | private static PointF XCap1_3D, XCap2_3D, YCap1_3D, YCap2_3D, ZCap1_3D, ZCap2_3D;
59 |
60 |
61 | private CanvasAidUtils() {
62 | }
63 |
64 |
65 | /**
66 | * draw 2D Coordinate Space.
67 | *
68 | * @param canvas Canvas
69 | */
70 | public static void draw2DCoordinateSpace(Canvas canvas) {
71 | if (!isDrawAid) return;
72 |
73 | initPaint();
74 | init2DPoint();
75 |
76 | canvas.save();
77 |
78 | CanvasUtils.drawLine(XHead_2D, XTail_2D, canvas, mPaint);
79 | CanvasUtils.drawLine(XHead_2D, XCap1_2D, canvas, mPaint);
80 | CanvasUtils.drawLine(XHead_2D, XCap2_2D, canvas, mPaint);
81 |
82 | CanvasUtils.drawLine(YHead_2D, YTail_2D, canvas, mPaint);
83 | CanvasUtils.drawLine(YHead_2D, YCap1_2D, canvas, mPaint);
84 | CanvasUtils.drawLine(YHead_2D, YCap2_2D, canvas, mPaint);
85 |
86 | canvas.restore();
87 | }
88 |
89 | /**
90 | * draw 3D Coordinate Space
91 | *
92 | * @param canvas Canvas
93 | */
94 | public static void draw3DCoordinateSpace(Canvas canvas) {
95 | if (!isDrawAid) return;
96 |
97 | initPaint();
98 | init3DPoint();
99 |
100 | canvas.save();
101 |
102 | CanvasUtils.drawLine(XHead_3D, XTail_3D, canvas, mPaint);
103 | CanvasUtils.drawLine(XHead_3D, XCap1_3D, canvas, mPaint);
104 | CanvasUtils.drawLine(XHead_3D, XCap2_3D, canvas, mPaint);
105 |
106 | CanvasUtils.drawLine(YHead_3D, YTail_3D, canvas, mPaint);
107 | CanvasUtils.drawLine(YHead_3D, YCap1_3D, canvas, mPaint);
108 | CanvasUtils.drawLine(YHead_3D, YCap2_3D, canvas, mPaint);
109 |
110 | CanvasUtils.drawLine(ZHead_3D, ZTail_3D, canvas, mPaint);
111 | CanvasUtils.drawLine(ZHead_3D, ZCap1_3D, canvas, mPaint);
112 | CanvasUtils.drawLine(ZHead_3D, ZCap2_3D, canvas, mPaint);
113 |
114 | canvas.restore();
115 | }
116 |
117 | private static void initPaint() {
118 | mPaint = new Paint();
119 | mPaint.setAntiAlias(true);
120 | mPaint.setColor(mLineColor);
121 | mPaint.setStyle(Paint.Style.STROKE);
122 | mPaint.setStrokeWidth(mLineWidth);
123 | mPaint.setStrokeCap(Paint.Cap.ROUND);
124 | }
125 |
126 | private static void init2DPoint() {
127 |
128 | XHead_2D = new PointF(+XAxisPosLen_2D, 0);
129 | XTail_2D = new PointF(-XAxisNegLen_2D, 0);
130 | XCap1_2D = new PointF(XAxisPosLen_2D - Cap_Head_Distance, +Cap_Axis_Distance);
131 | XCap2_2D = new PointF(XAxisPosLen_2D - Cap_Head_Distance, -Cap_Axis_Distance);
132 |
133 | YHead_2D = new PointF(0, +YAxisPosLen_2D);
134 | YTail_2D = new PointF(0, -YAxisNegLen_2D);
135 | YCap1_2D = new PointF(+Cap_Axis_Distance, YAxisPosLen_2D - Cap_Head_Distance);
136 | YCap2_2D = new PointF(-Cap_Axis_Distance, YAxisPosLen_2D - Cap_Head_Distance);
137 | }
138 |
139 | private static void init3DPoint() {
140 |
141 | XHead_3D = new PointF(+XAxisPosLen_3D, 0);
142 | XTail_3D = new PointF(-XAxisNegLen_3D, 0);
143 | XCap1_3D = new PointF(XAxisPosLen_3D - Cap_Head_Distance, +Cap_Axis_Distance);
144 | XCap2_3D = new PointF(XAxisPosLen_3D - Cap_Head_Distance, -Cap_Axis_Distance);
145 |
146 | YHead_3D = new PointF(0, -YAxisPosLen_3D);
147 | YTail_3D = new PointF(0, +YAxisNegLen_3D);
148 | YCap1_3D = new PointF(+Cap_Axis_Distance, -YAxisPosLen_3D + Cap_Head_Distance);
149 | YCap2_3D = new PointF(-Cap_Axis_Distance, -YAxisPosLen_3D + Cap_Head_Distance);
150 |
151 | float zl = convert_3D_to_2D(ZAxisPosLen_3D);
152 | float nzl = convert_3D_to_2D(ZAxisNegLen_3D);
153 | float CAD = convert_3D_to_2D(Cap_Axis_Distance);
154 | float CHD = convert_3D_to_2D(Cap_Head_Distance);
155 | ZHead_3D = new PointF(zl, -zl);
156 | ZTail_3D = new PointF(-nzl, nzl);
157 | ZCap1_3D = new PointF(ZHead_3D.x - CHD - CAD, ZHead_3D.y + CHD - CAD);
158 | ZCap2_3D = new PointF(ZHead_3D.x - CHD + CAD, ZHead_3D.y + CHD + CAD);
159 | }
160 |
161 | private static float convert_3D_to_2D(float l) {
162 | return l * 3 / 4;
163 | }
164 |
165 | public static boolean isDrawAid() {
166 | return isDrawAid;
167 | }
168 |
169 | public static void setDrawAid(boolean isDraw) {
170 | CanvasAidUtils.isDrawAid = isDraw;
171 | }
172 |
173 |
174 | /**
175 | * set 2D axis length
176 | *
177 | * @param lenX x axis length
178 | * @param lenY y axis length
179 | */
180 | public static void set2DAxisLength(float lenX, float lenY) {
181 | XAxisPosLen_2D = XAxisNegLen_2D = lenX;
182 | YAxisPosLen_2D = YAxisNegLen_2D = lenY;
183 | }
184 |
185 | /**
186 | * set 2D axis length
187 | *
188 | * @param lenPX x axis positive length
189 | * @param lenNX x axis negative length
190 | * @param lenPY y axis positive length
191 | * @param lenNY y axis negative length
192 | */
193 | public static void set2DAxisLength(float lenPX, float lenNX, float lenPY, float lenNY) {
194 | XAxisPosLen_2D = lenPX;
195 | YAxisPosLen_2D = lenPY;
196 | XAxisNegLen_2D = lenNX;
197 | YAxisNegLen_2D = lenNY;
198 | }
199 |
200 | /**
201 | * set 3D axis length
202 | *
203 | * @param lenX x axis length
204 | * @param lenY y axis length
205 | * @param lenZ z axis length
206 | */
207 | public static void set3DAxisLength(float lenX, float lenY, float lenZ) {
208 | XAxisPosLen_3D = XAxisNegLen_3D = lenX;
209 | YAxisPosLen_3D = YAxisNegLen_3D = lenY;
210 | ZAxisPosLen_3D = ZAxisNegLen_3D = lenZ;
211 | }
212 |
213 | /**
214 | * set 3D axis length
215 | *
216 | * @param lenPX x axis positive length
217 | * @param lenNX x axis negative length
218 | * @param lenPY y axis positive length
219 | * @param lenNY y axis negative length
220 | * @param lenPZ z axis positive length
221 | * @param lenNZ z axis negative length
222 | */
223 | public static void set3DAxisLength(float lenPX, float lenNX, float lenPY, float lenNY, float lenPZ, float lenNZ) {
224 | XAxisPosLen_3D = lenPX;
225 | YAxisPosLen_3D = lenPY;
226 | ZAxisPosLen_3D = lenPZ;
227 | XAxisNegLen_3D = lenNX;
228 | YAxisNegLen_3D = lenNY;
229 | ZAxisNegLen_3D = lenNZ;
230 | }
231 |
232 | /**
233 | * set axis line width
234 | *
235 | * @param width width
236 | */
237 | public static void setLineWidth(int width) {
238 | CanvasAidUtils.mLineWidth = width;
239 | }
240 |
241 | /**
242 | * set axis line color
243 | *
244 | * @param color
245 | */
246 | public static void setLineColor(int color) {
247 | CanvasAidUtils.mLineColor = color;
248 | }
249 | }
250 |
--------------------------------------------------------------------------------
/Library/src/main/java/com/gcssloop/view/helper/ApiHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 GcsSloop
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Last modified 2016-12-03 22:55:55
17 | *
18 | */
19 | package com.gcssloop.view.helper;
20 | import android.app.admin.DevicePolicyManager;
21 | import android.content.ComponentName;
22 | import android.hardware.Camera;
23 | import android.os.Build;
24 | import android.provider.MediaStore.MediaColumns;
25 | import android.view.View;
26 | import android.view.WindowManager;
27 | import java.lang.reflect.Field;
28 | public class ApiHelper {
29 | public static interface VERSION_CODES {
30 | // These value are copied from Build.VERSION_CODES
31 | public static final int GINGERBREAD_MR1 = 10;
32 | public static final int HONEYCOMB = 11;
33 | public static final int HONEYCOMB_MR1 = 12;
34 | public static final int HONEYCOMB_MR2 = 13;
35 | public static final int ICE_CREAM_SANDWICH = 14;
36 | public static final int ICE_CREAM_SANDWICH_MR1 = 15;
37 | public static final int JELLY_BEAN = 16;
38 | public static final int JELLY_BEAN_MR1 = 17;
39 | public static final int JELLY_BEAN_MR2 = 18;
40 | }
41 | public static final boolean AT_LEAST_16 = Build.VERSION.SDK_INT >= 16;
42 | public static final boolean USE_888_PIXEL_FORMAT =
43 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
44 | public static final boolean ENABLE_PHOTO_EDITOR =
45 | Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
46 | public static final boolean HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE =
47 | hasField(View.class, "SYSTEM_UI_FLAG_LAYOUT_STABLE");
48 | public static final boolean HAS_VIEW_SYSTEM_UI_FLAG_HIDE_NAVIGATION =
49 | hasField(View.class, "SYSTEM_UI_FLAG_HIDE_NAVIGATION");
50 | public static final boolean HAS_MEDIA_COLUMNS_WIDTH_AND_HEIGHT =
51 | hasField(MediaColumns.class, "WIDTH");
52 | public static final boolean HAS_REUSING_BITMAP_IN_BITMAP_REGION_DECODER =
53 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
54 | public static final boolean HAS_REUSING_BITMAP_IN_BITMAP_FACTORY =
55 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
56 | public static final boolean HAS_SET_BEAM_PUSH_URIS =
57 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
58 | public static final boolean HAS_SET_DEFALT_BUFFER_SIZE = hasMethod(
59 | "android.graphics.SurfaceTexture", "setDefaultBufferSize",
60 | int.class, int.class);
61 | public static final boolean HAS_RELEASE_SURFACE_TEXTURE = hasMethod(
62 | "android.graphics.SurfaceTexture", "release");
63 | public static final boolean HAS_SURFACE_TEXTURE =
64 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
65 | public static final boolean HAS_MTP =
66 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1;
67 | public static final boolean HAS_AUTO_FOCUS_MOVE_CALLBACK =
68 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
69 | public static final boolean HAS_REMOTE_VIEWS_SERVICE =
70 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
71 | public static final boolean HAS_INTENT_EXTRA_LOCAL_ONLY =
72 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
73 | public static final boolean HAS_SET_SYSTEM_UI_VISIBILITY =
74 | hasMethod(View.class, "setSystemUiVisibility", int.class);
75 | public static final boolean HAS_FACE_DETECTION;
76 | static {
77 | boolean hasFaceDetection = false;
78 | try {
79 | Class> listenerClass = Class.forName(
80 | "android.hardware.Camera$FaceDetectionListener");
81 | hasFaceDetection =
82 | hasMethod(Camera.class, "setFaceDetectionListener", listenerClass) &&
83 | hasMethod(Camera.class, "startFaceDetection") &&
84 | hasMethod(Camera.class, "stopFaceDetection") &&
85 | hasMethod(Camera.Parameters.class, "getMaxNumDetectedFaces");
86 | } catch (Throwable t) {
87 | }
88 | HAS_FACE_DETECTION = hasFaceDetection;
89 | }
90 | public static final boolean HAS_GET_CAMERA_DISABLED =
91 | hasMethod(DevicePolicyManager.class, "getCameraDisabled", ComponentName.class);
92 | public static final boolean HAS_MEDIA_ACTION_SOUND =
93 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
94 | public static final boolean HAS_TIME_LAPSE_RECORDING =
95 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
96 | public static final boolean HAS_ZOOM_WHEN_RECORDING =
97 | Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
98 | public static final boolean HAS_CAMERA_FOCUS_AREA =
99 | Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
100 | public static final boolean HAS_CAMERA_METERING_AREA =
101 | Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
102 | public static final boolean HAS_MOTION_EVENT_TRANSFORM =
103 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
104 | public static final boolean HAS_EFFECTS_RECORDING = false;
105 | // "Background" filter does not have "context" input port in jelly bean.
106 | public static final boolean HAS_EFFECTS_RECORDING_CONTEXT_INPUT =
107 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1;
108 | public static final boolean HAS_GET_SUPPORTED_VIDEO_SIZE =
109 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
110 | public static final boolean HAS_SET_ICON_ATTRIBUTE =
111 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
112 | public static final boolean HAS_MEDIA_PROVIDER_FILES_TABLE =
113 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
114 | public static final boolean HAS_SURFACE_TEXTURE_RECORDING =
115 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
116 | public static final boolean HAS_ACTION_BAR =
117 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
118 | // Ex: View.setTranslationX.
119 | public static final boolean HAS_VIEW_TRANSFORM_PROPERTIES =
120 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
121 | public static final boolean HAS_CAMERA_HDR =
122 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1;
123 | public static final boolean HAS_OPTIONS_IN_MUTABLE =
124 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
125 | public static final boolean CAN_START_PREVIEW_IN_JPEG_CALLBACK =
126 | Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
127 | public static final boolean HAS_VIEW_PROPERTY_ANIMATOR =
128 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1;
129 | public static final boolean HAS_POST_ON_ANIMATION =
130 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
131 | public static final boolean HAS_ANNOUNCE_FOR_ACCESSIBILITY =
132 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
133 | public static final boolean HAS_OBJECT_ANIMATION =
134 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
135 | public static final boolean HAS_GLES20_REQUIRED =
136 | Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
137 | public static final boolean HAS_ROTATION_ANIMATION =
138 | hasField(WindowManager.LayoutParams.class, "rotationAnimation");
139 | public static final boolean HAS_ORIENTATION_LOCK =
140 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2;
141 | public static final boolean HAS_CANCELLATION_SIGNAL =
142 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
143 | public static final boolean HAS_MEDIA_MUXER =
144 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2;
145 | public static final boolean HAS_DISPLAY_LISTENER =
146 | Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1;
147 |
148 | public static int getIntFieldIfExists(Class> klass, String fieldName,
149 | Class> obj, int defaultVal) {
150 | try {
151 | Field f = klass.getDeclaredField(fieldName);
152 | return f.getInt(obj);
153 | } catch (Exception e) {
154 | return defaultVal;
155 | }
156 | }
157 |
158 | public static boolean hasField(Class> klass, String fieldName) {
159 | try {
160 | klass.getDeclaredField(fieldName);
161 | return true;
162 | } catch (NoSuchFieldException e) {
163 | return false;
164 | }
165 | }
166 |
167 | public static boolean hasMethod(String className, String methodName,
168 | Class>... parameterTypes) {
169 | try {
170 | Class> klass = Class.forName(className);
171 | klass.getDeclaredMethod(methodName, parameterTypes);
172 | return true;
173 | } catch (Throwable th) {
174 | return false;
175 | }
176 | }
177 |
178 | public static boolean hasMethod(
179 | Class> klass, String methodName, Class> ... paramTypes) {
180 | try {
181 | klass.getDeclaredMethod(methodName, paramTypes);
182 | return true;
183 | } catch (NoSuchMethodException e) {
184 | return false;
185 | }
186 | }
187 | }
--------------------------------------------------------------------------------
/Library/Library.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | generateDebugSources
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 |
--------------------------------------------------------------------------------
/Sample/Sample.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | generateDebugSources
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 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------