├── .gitignore
├── .travis.yml
├── README-cn.md
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── jayfeng
│ │ └── lesscode
│ │ └── app
│ │ ├── MyApp.java
│ │ ├── activity
│ │ ├── ActivityActivity.java
│ │ ├── AppActivity.java
│ │ ├── BitmapActivity.java
│ │ ├── CacheActivity.java
│ │ ├── DeviceActivity.java
│ │ ├── DisplayActivity.java
│ │ ├── DrawableActivity.java
│ │ ├── EncodeActivity.java
│ │ ├── FileActivity.java
│ │ ├── HttpActivity.java
│ │ ├── KeyboradActivity.java
│ │ ├── LogActivity.java
│ │ ├── MainActivity.java
│ │ ├── NetworkActivity.java
│ │ ├── ResourceActivity.java
│ │ ├── SerializeActivity.java
│ │ ├── SharedPreferenceActivity.java
│ │ ├── StorageActivity.java
│ │ ├── ToastActivity.java
│ │ └── ViewActivity.java
│ │ └── model
│ │ ├── LessItem.java
│ │ └── Person.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ ├── girl.jpg
│ ├── girl2.jpg
│ ├── ic_launcher.png
│ └── xinru.jpg
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── drawable
│ ├── list_divider.xml
│ ├── list_divider_p.xml
│ └── list_item_bg.xml
│ ├── layout
│ ├── activity_activity.xml
│ ├── activity_adapter.xml
│ ├── activity_adapter_base.xml
│ ├── activity_adapter_pager.xml
│ ├── activity_adapter_recycler.xml
│ ├── activity_app.xml
│ ├── activity_bitmap.xml
│ ├── activity_cache.xml
│ ├── activity_device.xml
│ ├── activity_display.xml
│ ├── activity_drawable.xml
│ ├── activity_encode.xml
│ ├── activity_file.xml
│ ├── activity_http.xml
│ ├── activity_keyborad.xml
│ ├── activity_log.xml
│ ├── activity_main.xml
│ ├── activity_main_list_item.xml
│ ├── activity_network.xml
│ ├── activity_resource.xml
│ ├── activity_shared_preference.xml
│ ├── activity_storage.xml
│ ├── activity_toast.xml
│ ├── activity_update.xml
│ ├── activity_view.xml
│ └── adapter_list_item_header.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── lesscode-core
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── jayfeng
│ │ └── lesscode
│ │ └── core
│ │ ├── $.java
│ │ ├── ActivityLess.java
│ │ ├── AlarmLess.java
│ │ ├── AppLess.java
│ │ ├── ApplicationLess.java
│ │ ├── BitmapLess.java
│ │ ├── CacheLess.java
│ │ ├── DeviceLess.java
│ │ ├── DisplayLess.java
│ │ ├── DrawableLess.java
│ │ ├── EncodeLess.java
│ │ ├── FileLess.java
│ │ ├── HttpLess.java
│ │ ├── ImageLess.java
│ │ ├── KeyBoardLess.java
│ │ ├── LogLess.java
│ │ ├── NetworkLess.java
│ │ ├── ResourceLess.java
│ │ ├── SerializeLess.java
│ │ ├── SharedPreferenceLess.java
│ │ ├── StorageLess.java
│ │ ├── ToastLess.java
│ │ ├── ViewLess.java
│ │ └── other
│ │ ├── DividerItemDecoration.java
│ │ ├── SpaceDividerView.java
│ │ ├── ViewThrottleClickListener.java
│ │ └── WeakHandler.java
│ └── res
│ ├── values-hdpi
│ └── bools.xml
│ ├── values-ldpi
│ └── bools.xml
│ ├── values-mdpi
│ └── bools.xml
│ ├── values-tvdpi
│ └── bools.xml
│ ├── values-xhdpi
│ └── bools.xml
│ ├── values-xxhdpi
│ └── bools.xml
│ ├── values-xxxhdpi
│ └── bools.xml
│ └── values
│ ├── attrs_space_divider_view.xml
│ └── strings.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 |
15 | # Local configuration file (sdk path, etc)
16 | local.properties
17 |
18 | # Eclipse project files
19 | .classpath
20 | .project
21 |
22 | # Android Studio
23 | .idea/
24 | .gradle
25 | /*/local.properties
26 | /*/out
27 | build
28 | /*/*/production
29 | *.iml
30 | *.iws
31 | *.ipr
32 | *~
33 | *.swp
34 | .DS_Store
35 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | android:
3 | components:
4 | # Uncomment the lines below if you want to
5 | # use the latest revision of Android SDK Tools
6 | # - platform-tools
7 | # - tools
8 |
9 | # The BuildTools version used by your project
10 | - tools
11 | - build-tools-23.0.2
12 |
13 | # The SDK version used to compile your project
14 | - android-23
15 | - extra-android-m2repository
16 |
--------------------------------------------------------------------------------
/README-cn.md:
--------------------------------------------------------------------------------
1 | # LessCode [](https://bintray.com/openproject/maven/lesscode) [](https://travis-ci.org/openproject/LessCode)
2 |
3 | 打造精简、高效的最好Android工具库!
4 |
5 | ## Overview
6 |
7 | > * 大量比原生更便捷的方法
8 | > * 高性能
9 | > * 易于集成
10 | > * 小体积 (60k+,开启混淆后更小)
11 | > * 开源
12 |
13 | ## Gradle
14 |
15 | ```groovy
16 | implementation 'com.jayfeng:lesscode-core:2.4.2'
17 | ```
18 |
19 | ## Features
20 | |源码|备注|
21 | |-------|-------|
22 | |ActivityLess|Activity相关辅助类:去标题,全屏,两次退出提示,优化Overdraw背景等|
23 | |AdapterLess|打造通用的BaseAdapter,PagerAdapter,RecyclerView.Adapter等|
24 | |AlarmLess|定时器相关|
25 | |AppLess|获取应用版本,名称,签名,清理缓存等|
26 | |BitmapLess|Bitmap处理相关|
27 | |CacheLess|缓存网络请求返回的json|
28 | |DeviceLess|获取设备信息,比如mac|
29 | |DisplayLess|屏幕相关,比如dp和px的转换,状态栏或者标题栏的高度,dpi判断|
30 | |DrawableLess|通用的着色方案|
31 | |EncodeLess|md5加密|
32 | |FileLess|文件处理相关|
33 | |HttpLess|简单的Http工具类,如果是专业用途还是用其他更强大的第三方库吧|
34 | |ImageLess|图片相关|
35 | |KeyBoardLess|输入法的弹出或隐藏|
36 | |LogLess|强大的Log库|
37 | |NetworkLess|网络判断|
38 | |ResourceLess|根据资源名获取ID|
39 | |SerializeLess|序列化和反序列化|
40 | |SharedPreferenceLess|简化和增强SharedPreference的操作|
41 | |StorageLess|手机存储相关,包括:手机内存,内置存储卡(Sdcard),外置存储卡(ExtSdcard)|
42 | |ToastLess|简化Toast的使用|
43 | |UpdateLess/UpdateService|简单但完整的自动更新实现,无缝对接(已分离到LessCode-Update项目)|
44 | |ViewLess|简化繁琐的findViewById和强制转换|
45 |
46 | ## Usage
47 |
48 | ####Config
49 | * Required
50 | ```java
51 | $.getInstance()
52 | .context(getApplicationContext())
53 | .build();
54 | ```
55 |
56 | * Optional
57 | ```java
58 | $.getInstance()
59 | .context(getApplicationContext())
60 | .log(BuildConfig.DEBUG, "LESSCODE") // LogLess - debug, tag
61 | .update(null, 5) // UpdateLess - null means the default value, 5 is the notification frequent, default is 5
62 | .http(5000, 5000) // HttpLess - default connect and read timeout
63 | .build();
64 | ```
65 |
66 | ####Android VS LessCode
67 |
68 | * ViewLess
69 | ```java
70 | // 强制转化View类型
71 | // Before
72 | ListView listView = (ListView) findViewById(R.id.list);
73 | // After
74 | ListView listView = ViewLess.$(this, R.id.list);
75 | ```
76 |
77 | * ActivityLess
78 | ```java
79 | // 无标题全屏
80 | // Before
81 | requestWindowFeature(Window.FEATURE_NO_TITLE);
82 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
83 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
84 | WindowManager.LayoutParams.FLAG_FULLSCREEN);
85 | // After
86 | ActivityLess.$noTitle(this);
87 | ActivityLess.$fullScreen(this);
88 | ```
89 |
90 | ## Proguard
91 | ```
92 | -dontwarn com.jayfeng.lesscode.**
93 | ```
94 |
95 | See more details on the [Wiki](https://github.com/openproject/LessCode/wiki)
96 |
97 | ## Alternative libraries
98 | * [xUtils3](https://github.com/wyouflf/xUtils3)
99 | * [LiteCommon](https://github.com/litesuits/android-common)
100 | * [TrineaAndroidCommon](https://github.com/Trinea/android-common)
101 | * [AndroidUtils](https://github.com/jingle1267/android-utils)
102 |
103 | ## Author
104 |
105 | > Author weibo:冯建V mail:673592063@qq.com QQ:673592063
106 |
107 | ## License
108 |
109 | ```
110 | Copyright (C) LessCode Open Source Project
111 |
112 | Licensed under the Apache License, Version 2.0 (the "License");
113 | you may not use this file except in compliance with the License.
114 | You may obtain a copy of the License at
115 |
116 | http://www.apache.org/licenses/LICENSE-2.0
117 |
118 | Unless required by applicable law or agreed to in writing, software
119 | distributed under the License is distributed on an "AS IS" BASIS,
120 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121 | See the License for the specific language governing permissions and
122 | limitations under the License.
123 | ```
124 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #### [中文版文档](https://github.com/openproject/LessCode/blob/master/README-cn.md)
2 |
3 | [](https://bintray.com/openproject/maven/lesscode)
4 | [](https://travis-ci.org/openproject/LessCode)
5 | [![MethodCount][methodcount-svg]][methodcount-link]
6 |
7 | # LessCode
8 | less code, more efficient for android, for the best android tools library!
9 |
10 | ## Overview
11 |
12 | > * support more effective methods than android
13 | > * high performence
14 | > * easy integration
15 | > * small size (only 45k~ by proguard)
16 | > * open source
17 |
18 | ## Gradle
19 |
20 | ```groovy
21 | implementation 'com.jayfeng:lesscode-core:2.4.2'
22 | ```
23 |
24 | ## Features
25 | |源码|备注|
26 | |-------|-------|
27 | |ActivityLess|Activity相关辅助类:去标题,全屏,两次退出提示,优化Overdraw背景等|
28 | |AdapterLess|打造通用的BaseAdapter,PagerAdapter,RecyclerView.Adapter等|
29 | |AlarmLess|定时器相关|
30 | |AppLess|获取应用版本,名称,签名,清理缓存等|
31 | |BitmapLess|Bitmap处理相关|
32 | |CacheLess|缓存网络请求返回的json|
33 | |DeviceLess|获取设备信息,比如mac|
34 | |DisplayLess|屏幕相关,比如dp和px的转换,状态栏或者标题栏的高度,dpi判断|
35 | |DrawableLess|通用的着色方案|
36 | |EncodeLess|md5加密|
37 | |FileLess|文件处理相关|
38 | |HttpLess|简单的Http工具类,如果是专业用途还是用其他更强大的第三方库吧|
39 | |ImageLess|图片相关|
40 | |KeyBoardLess|输入法的弹出或隐藏|
41 | |LogLess|强大的Log库|
42 | |NetworkLess|网络判断|
43 | |ResourceLess|根据资源名获取ID|
44 | |SerializeLess|序列化和反序列化|
45 | |SharedPreferenceLess|简化和增强SharedPreference的操作|
46 | |StorageLess|手机存储相关,包括:手机内存,内置存储卡(Sdcard),外置存储卡(ExtSdcard)|
47 | |ToastLess|简化Toast的使用|
48 | |UpdateLess/UpdateService|简单但完整的自动更新实现,无缝对接(已分离到LessCode-Update项目)|
49 | |ViewLess|简化繁琐的findViewById和强制转换|
50 |
51 | ## Usage
52 |
53 | ####Config
54 | * Required
55 | ```java
56 | $.getInstance()
57 | .context(getApplicationContext())
58 | .build();
59 | ```
60 |
61 | * Optional
62 | ```java
63 | $.getInstance()
64 | .context(getApplicationContext())
65 | .log(BuildConfig.DEBUG, "LESSCODE") // LogLess - debug, tag
66 | .update(null, 5) // UpdateLess - null means the default value, 5 is the notification frequent, default is 5
67 | .http(5000, 5000) // HttpLess - default connect and read timeout
68 | .build();
69 | ```
70 |
71 | ####Android VS LessCode
72 |
73 | * ViewLess
74 | ```java
75 | // 强制转化View类型
76 | // Before
77 | ListView listView = (ListView) findViewById(R.id.list);
78 | // After
79 | ListView listView = ViewLess.$(this, R.id.list);
80 | ```
81 |
82 | * ActivityLess
83 | ```java
84 | // 无标题全屏
85 | // Before
86 | requestWindowFeature(Window.FEATURE_NO_TITLE);
87 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
88 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
89 | WindowManager.LayoutParams.FLAG_FULLSCREEN);
90 | // After
91 | ActivityLess.$noTitle(this);
92 | ActivityLess.$fullScreen(this);
93 | ```
94 |
95 | ## Proguard
96 | ```
97 | -dontwarn com.jayfeng.lesscode.**
98 | ```
99 |
100 | See more details on the [Wiki](https://github.com/openproject/LessCode/wiki)
101 |
102 | ## Alternative libraries
103 | * [xUtils3](https://github.com/wyouflf/xUtils3)
104 | * [LiteCommon](https://github.com/litesuits/android-common)
105 | * [TrineaAndroidCommon](https://github.com/Trinea/android-common)
106 | * [AndroidUtils](https://github.com/jingle1267/android-utils)
107 |
108 | ## Author
109 |
110 | > Author weibo:冯建V mail:673592063@qq.com QQ:673592063
111 |
112 | ## License
113 |
114 | ```
115 | Copyright (C) LessCode Open Source Project
116 |
117 | Licensed under the Apache License, Version 2.0 (the "License");
118 | you may not use this file except in compliance with the License.
119 | You may obtain a copy of the License at
120 |
121 | http://www.apache.org/licenses/LICENSE-2.0
122 |
123 | Unless required by applicable law or agreed to in writing, software
124 | distributed under the License is distributed on an "AS IS" BASIS,
125 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126 | See the License for the specific language governing permissions and
127 | limitations under the License.
128 | ```
129 | [methodcount-svg]: https://img.shields.io/badge/Methodscount-717-e91e63.svg
130 | [methodcount-link]: http://www.methodscount.com/?lib=com.jayfeng%3Alesscode-core%3A0.9.6.1
131 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | buildToolsVersion '27.0.3'
6 |
7 | defaultConfig {
8 | applicationId "com.jayfeng.lesscode.app"
9 | minSdkVersion 14
10 | targetSdkVersion 27
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 |
21 | lintOptions {
22 | abortOnError false
23 | }
24 | }
25 |
26 | dependencies {
27 | compile fileTree(include: ['*.jar'], dir: 'libs')
28 | compile project(':lesscode-core')
29 | }
30 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/jay/tools/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 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
27 |
30 |
33 |
36 |
39 |
42 |
45 |
48 |
51 |
54 |
57 |
60 |
63 |
66 |
69 |
72 |
75 |
78 |
81 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/MyApp.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app;
2 |
3 | import android.app.Application;
4 |
5 | import com.jayfeng.lesscode.core.$;
6 |
7 | public class MyApp extends Application {
8 |
9 | @Override
10 | public void onCreate() {
11 | super.onCreate();
12 |
13 | $.getInstance()
14 | .context(getApplicationContext())
15 | .log(BuildConfig.DEBUG, "LESSCODE")
16 | .update(null, 4)
17 | .http(5000, 5000)
18 | .build();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/ActivityActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 | import com.jayfeng.lesscode.core.ActivityLess;
8 |
9 | public class ActivityActivity extends Activity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | ActivityLess.$noTitle(this);
14 | ActivityLess.$fullScreen(this);
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_activity);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/AppActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.Button;
7 | import android.widget.EditText;
8 |
9 | import com.jayfeng.lesscode.app.R;
10 | import com.jayfeng.lesscode.core.AppLess;
11 | import com.jayfeng.lesscode.core.FileLess;
12 | import com.jayfeng.lesscode.core.StorageLess;
13 | import com.jayfeng.lesscode.core.ToastLess;
14 | import com.jayfeng.lesscode.core.ViewLess;
15 |
16 | import java.io.File;
17 |
18 | public class AppActivity extends Activity {
19 |
20 | private EditText deleteDirPathView;
21 | private Button deleteButton;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_app);
27 |
28 | ToastLess.$(this, "current package:" + AppLess.$running(getPackageName())
29 | + ", else package:" + AppLess.$running("com.marriage"));
30 |
31 | deleteDirPathView = ViewLess.$(this, R.id.del_dir_path);
32 | deleteButton = ViewLess.$(this, R.id.del_dir_btn);
33 |
34 | deleteDirPathView.setText(StorageLess.Sdcard.$path().getPath() + "/test");
35 |
36 | deleteButton.setOnClickListener(new View.OnClickListener() {
37 | @Override
38 | public void onClick(View v) {
39 | String path = deleteDirPathView.getText().toString();
40 | File dir = new File(path);
41 | FileLess.$del(dir, true);
42 | }
43 | });
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/BitmapActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.drawable.BitmapDrawable;
6 | import android.os.Bundle;
7 | import android.widget.ImageView;
8 | import android.widget.TextView;
9 |
10 | import com.jayfeng.lesscode.app.R;
11 | import com.jayfeng.lesscode.core.BitmapLess;
12 | import com.jayfeng.lesscode.core.DeviceLess;
13 | import com.jayfeng.lesscode.core.DisplayLess;
14 | import com.jayfeng.lesscode.core.ViewLess;
15 |
16 | public class BitmapActivity extends Activity {
17 |
18 | private ImageView roundImageView;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_bitmap);
24 |
25 | roundImageView = ViewLess.$(this, R.id.image_round);
26 |
27 | Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.girl2)).getBitmap();
28 | bitmap = BitmapLess.$gray(bitmap, true);
29 | roundImageView.setImageBitmap(bitmap);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/CacheActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapRegionDecoder;
6 | import android.graphics.Matrix;
7 | import android.graphics.drawable.BitmapDrawable;
8 | import android.os.Bundle;
9 | import android.support.v4.util.LruCache;
10 |
11 | import com.jayfeng.lesscode.app.R;
12 |
13 | public class CacheActivity extends Activity {
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_cache);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/DeviceActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.widget.TextView;
7 |
8 | import com.jayfeng.lesscode.app.R;
9 | import com.jayfeng.lesscode.core.DeviceLess;
10 | import com.jayfeng.lesscode.core.DisplayLess;
11 | import com.jayfeng.lesscode.core.ToastLess;
12 | import com.jayfeng.lesscode.core.ViewLess;
13 |
14 | public class DeviceActivity extends Activity {
15 |
16 | private TextView macView;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_device);
22 |
23 | macView = ViewLess.$(this, R.id.mac);
24 | macView.setText(DeviceLess.$mac());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/DisplayActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 |
7 | import com.jayfeng.lesscode.app.R;
8 | import com.jayfeng.lesscode.core.DisplayLess;
9 | import com.jayfeng.lesscode.core.ToastLess;
10 |
11 | public class DisplayActivity extends Activity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_display);
17 |
18 | ToastLess.$(this, DisplayLess.$width(this) + "x" + DisplayLess.$height(this));
19 |
20 | new Handler().postDelayed(new Runnable() {
21 | @Override
22 | public void run() {
23 | ToastLess.$(DisplayActivity.this, "status bar height:" + DisplayLess.$statusBarHeight(DisplayActivity.this)
24 | + ", title bar height:" + DisplayLess.$titleBarHeight(DisplayActivity.this));
25 | }
26 | }, 2000);
27 | ToastLess.$(this, "status bar height with reflect:" + DisplayLess.$statusBarHeight(getResources()));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/DrawableActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.content.res.ColorStateList;
5 | import android.graphics.Color;
6 | import android.graphics.PorterDuff;
7 | import android.graphics.drawable.Drawable;
8 | import android.os.Bundle;
9 | import android.view.View;
10 | import android.widget.AdapterView;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.ImageView;
13 | import android.widget.Spinner;
14 |
15 | import com.jayfeng.lesscode.app.R;
16 | import com.jayfeng.lesscode.core.DrawableLess;
17 | import com.jayfeng.lesscode.core.ToastLess;
18 | import com.jayfeng.lesscode.core.ViewLess;
19 |
20 | public class DrawableActivity extends Activity {
21 |
22 | private static final PorterDuff.Mode[] tintModeArray = {
23 | // PorterDuff.Mode.ADD,
24 | PorterDuff.Mode.CLEAR,
25 | PorterDuff.Mode.DARKEN,
26 | PorterDuff.Mode.DST,
27 | PorterDuff.Mode.DST_ATOP,
28 | PorterDuff.Mode.DST_IN,
29 | PorterDuff.Mode.DST_OUT,
30 | PorterDuff.Mode.DST_OVER,
31 | PorterDuff.Mode.LIGHTEN,
32 | PorterDuff.Mode.MULTIPLY,
33 | // PorterDuff.Mode.OVERLAY,
34 | PorterDuff.Mode.SCREEN,
35 | PorterDuff.Mode.SRC,
36 | PorterDuff.Mode.SRC_ATOP,
37 | PorterDuff.Mode.SRC_IN,
38 | PorterDuff.Mode.SRC_OUT,
39 | PorterDuff.Mode.SRC_OVER,
40 | PorterDuff.Mode.XOR
41 | };
42 |
43 | private ImageView imageView;
44 | private Spinner tintModeView;
45 |
46 | private ArrayAdapter tintModeAdapter;
47 |
48 | @Override
49 | protected void onCreate(Bundle savedInstanceState) {
50 | super.onCreate(savedInstanceState);
51 | setContentView(R.layout.activity_drawable);
52 |
53 | imageView = ViewLess.$(this, R.id.image);
54 | tintModeView = ViewLess.$(this, R.id.tintMode);
55 |
56 | tintModeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, tintModeArray);
57 | tintModeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
58 | tintModeView.setAdapter(tintModeAdapter);
59 |
60 | tintModeView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
61 | @Override
62 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
63 | Drawable tintDrawable = DrawableLess.$tint(
64 | getResources().getDrawable(R.drawable.ic_launcher),
65 | ColorStateList.valueOf(Color.RED),
66 | tintModeArray[position]
67 | );
68 |
69 | ToastLess.$(DrawableActivity.this, tintModeArray[position].name());
70 |
71 | imageView.setImageDrawable(tintDrawable);
72 | }
73 |
74 | @Override
75 | public void onNothingSelected(AdapterView> parent) {
76 |
77 | }
78 | });
79 |
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/EncodeActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 |
8 | public class EncodeActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_encode);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/FileActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 |
8 | public class FileActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_file);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/HttpActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 |
8 | public class HttpActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_http);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/KeyboradActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.Button;
7 | import android.widget.EditText;
8 |
9 | import com.jayfeng.lesscode.app.R;
10 | import com.jayfeng.lesscode.core.KeyBoardLess;
11 | import com.jayfeng.lesscode.core.ViewLess;
12 |
13 | public class KeyboradActivity extends Activity {
14 |
15 | private EditText editText;
16 | private Button showKeyboradButton;
17 | private Button hideKeyboradButton;
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_keyborad);
23 |
24 | editText = ViewLess.$(this, R.id.edit);
25 | showKeyboradButton = ViewLess.$(this, R.id.show);
26 | hideKeyboradButton = ViewLess.$(this, R.id.hide);
27 |
28 | showKeyboradButton.setOnClickListener(new View.OnClickListener() {
29 | @Override
30 | public void onClick(View v) {
31 | KeyBoardLess.$show(KeyboradActivity.this, editText);
32 | }
33 | });
34 |
35 | hideKeyboradButton.setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View v) {
38 | KeyBoardLess.$hide(KeyboradActivity.this, editText);
39 | }
40 | });
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/LogActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 | import com.jayfeng.lesscode.core.LogLess;
8 |
9 | public class LogActivity extends Activity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_log);
15 |
16 | LogLess.$d("xxxxxxx");
17 | LogLess.$e("yyyyy");
18 | LogLess.$json("{\"a\":\"aValue\"}", "test");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Environment;
6 | import android.widget.BaseAdapter;
7 | import android.widget.ListView;
8 |
9 | import com.jayfeng.lesscode.app.R;
10 | import com.jayfeng.lesscode.app.model.LessItem;
11 | import com.jayfeng.lesscode.core.ActivityLess;
12 | import com.jayfeng.lesscode.core.HttpLess;
13 | import com.jayfeng.lesscode.core.LogLess;
14 | import com.jayfeng.lesscode.core.ToastLess;
15 | import com.jayfeng.lesscode.core.ViewLess;
16 |
17 | import java.io.File;
18 | import java.net.URLEncoder;
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 |
23 | public class MainActivity extends Activity {
24 |
25 | List list;
26 |
27 | ListView listView;
28 |
29 | BaseAdapter adapter;
30 |
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 |
35 | setContentView(R.layout.activity_main);
36 | listView = ViewLess.$(this, R.id.listview);
37 |
38 | initData();
39 |
40 | final File mDestDir = new File(Environment.getExternalStorageDirectory().getPath() + "/lesscode-download");
41 | if (mDestDir.exists() && !mDestDir.isDirectory()) {
42 | mDestDir.delete();
43 | }
44 | if (mDestDir.exists() || mDestDir.mkdirs()) {
45 |
46 | }
47 | final File mDestFile = new File(mDestDir.getPath() + "/" + URLEncoder.encode("http://www.vpngo.com/download/vpngo-release-v1.3.1-46.apk"));
48 | new Thread() {
49 | @Override
50 | public void run() {
51 | try {
52 | HttpLess.$download("http://www.vpngo.com/download/vpngo-release-v1.3.1-46.apk", mDestFile, false, new HttpLess.DownloadCallBack() {
53 | @Override
54 | public void onDownloading(int progress) {
55 |
56 | }
57 |
58 | @Override
59 | public void onDownloaded() {
60 | LogLess.$d("下载完成");
61 | }
62 | });
63 | } catch (Exception e) {
64 | e.printStackTrace();
65 | LogLess.$d(e.getMessage());
66 | }
67 | }
68 | }.start();
69 |
70 |
71 | // adapter = AdapterLess.$base(this, list, R.layout.activity_main_list_item,
72 | // new AdapterLess.CallBack() {
73 | // @Override
74 | // public View getView(int position, View convertView, AdapterLess.ViewHolder holder, LessItem lessItem) {
75 | // TextView nameView = holder.$view(convertView, R.id.name);
76 | // nameView.setText(lessItem.getName());
77 | // return convertView;
78 | // }
79 | // });
80 | // listView.setAdapter(adapter);
81 | // listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
82 | // @Override
83 | // public void onItemClick(AdapterView> parent, View view, int position, long id) {
84 | // Intent intent = new Intent();
85 | // intent.setClassName(MainActivity.this, "com.jayfeng.lesscode.app.activity." + list.get(position).getClassName());
86 | // startActivity(intent);
87 | // }
88 | // });
89 | //
90 | // LogLess.$d("network: %s, type: %s", NetworkLess.$online(), NetworkLess.$type());
91 | //
92 | // Person person = new Person("fengj");
93 | // SerializeLess.$se(new File(getCacheDir(), "person").getAbsolutePath(), person);
94 | //
95 | // Person person1 = SerializeLess.$de(new File(getCacheDir(), "person").getAbsolutePath());
96 | // ToastLess.$(this, person1.getName());
97 |
98 | }
99 |
100 | private void initData() {
101 | list = new ArrayList<>();
102 |
103 | LessItem lessItem = new LessItem();
104 | lessItem.setName("ActivityLess的使用");
105 | lessItem.setClassName("ActivityActivity");
106 | list.add(lessItem);
107 |
108 | lessItem = new LessItem();
109 | lessItem.setName("AppLess的使用");
110 | lessItem.setClassName("AppActivity");
111 | list.add(lessItem);
112 |
113 | lessItem = new LessItem();
114 | lessItem.setName("BitmapLess的使用");
115 | lessItem.setClassName("BitmapActivity");
116 | list.add(lessItem);
117 |
118 | lessItem = new LessItem();
119 | lessItem.setName("CacheLess的使用");
120 | lessItem.setClassName("CacheActivity");
121 | list.add(lessItem);
122 |
123 | lessItem = new LessItem();
124 | lessItem.setName("DeviceLess的使用");
125 | lessItem.setClassName("DeviceActivity");
126 | list.add(lessItem);
127 |
128 | lessItem = new LessItem();
129 | lessItem.setName("DisplayLess的使用");
130 | lessItem.setClassName("DisplayActivity");
131 | list.add(lessItem);
132 |
133 | lessItem = new LessItem();
134 | lessItem.setName("DrawableLess的使用");
135 | lessItem.setClassName("DrawableActivity");
136 | list.add(lessItem);
137 |
138 | lessItem = new LessItem();
139 | lessItem.setName("EncodeLess的使用");
140 | lessItem.setClassName("EncodeActivity");
141 | list.add(lessItem);
142 |
143 | lessItem = new LessItem();
144 | lessItem.setName("FileLess的使用");
145 | lessItem.setClassName("FileActivity");
146 | list.add(lessItem);
147 |
148 | lessItem = new LessItem();
149 | lessItem.setName("HttpLess的使用");
150 | lessItem.setClassName("HttpActivity");
151 | list.add(lessItem);
152 |
153 | lessItem = new LessItem();
154 | lessItem.setName("KeyboradLess的使用");
155 | lessItem.setClassName("KeyboradActivity");
156 | list.add(lessItem);
157 |
158 | lessItem = new LessItem();
159 | lessItem.setName("LogLess的使用");
160 | lessItem.setClassName("LogActivity");
161 | list.add(lessItem);
162 |
163 | lessItem = new LessItem();
164 | lessItem.setName("NetworkLess的使用");
165 | lessItem.setClassName("NetworkActivity");
166 | list.add(lessItem);
167 |
168 | lessItem = new LessItem();
169 | lessItem.setName("ResourceLess的使用");
170 | lessItem.setClassName("ResourceActivity");
171 | list.add(lessItem);
172 |
173 | lessItem = new LessItem();
174 | lessItem.setName("SharedPreferenceLess的使用");
175 | lessItem.setClassName("SharedPreferenceActivity");
176 | list.add(lessItem);
177 |
178 | lessItem = new LessItem();
179 | lessItem.setName("StorageLess的使用");
180 | lessItem.setClassName("StorageActivity");
181 | list.add(lessItem);
182 |
183 | lessItem = new LessItem();
184 | lessItem.setName("ToastLess的使用");
185 | lessItem.setClassName("ToastActivity");
186 | list.add(lessItem);
187 |
188 | lessItem = new LessItem();
189 | lessItem.setName("ViewLess的使用");
190 | lessItem.setClassName("ViewActivity");
191 | list.add(lessItem);
192 | }
193 |
194 | @Override
195 | public void onBackPressed() {
196 | if (ActivityLess.$exitTwice()) {
197 | super.onBackPressed();
198 | } else {
199 | ToastLess.$(this, "再按一次退出程序");
200 | }
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/NetworkActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 |
8 | public class NetworkActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_network);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/ResourceActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 |
8 | public class ResourceActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_resource);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/SerializeActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | /**
4 | * Created by fengjian on 15/7/2.
5 | */
6 | public class SerializeActivity {
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/SharedPreferenceActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 | import com.jayfeng.lesscode.core.LogLess;
8 | import com.jayfeng.lesscode.core.SharedPreferenceLess;
9 |
10 | public class SharedPreferenceActivity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_shared_preference);
16 |
17 |
18 | SharedPreferenceLess.$put("key1", 333);
19 | SharedPreferenceLess.$put("key2", 0.5f);
20 | SharedPreferenceLess.$put("key3", true);
21 | SharedPreferenceLess.$put("key4", 100000L);
22 | SharedPreferenceLess.$put("key5", "i am a string");
23 | SharedPreferenceLess.$put("key5", null);
24 |
25 | LogLess.$d(SharedPreferenceLess.$get("key1", 0) + "");
26 | LogLess.$d(SharedPreferenceLess.$get("key2", 0f) + "");
27 | LogLess.$d(SharedPreferenceLess.$get("key3", false) + "");
28 | LogLess.$d(SharedPreferenceLess.$get("key4", 0L) + "");
29 | LogLess.$d(SharedPreferenceLess.$get("key5", ""));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/StorageActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.text.format.Formatter;
6 |
7 | import com.jayfeng.lesscode.app.R;
8 | import com.jayfeng.lesscode.core.LogLess;
9 | import com.jayfeng.lesscode.core.StorageLess;
10 | import com.jayfeng.lesscode.core.ToastLess;
11 |
12 | public class StorageActivity extends Activity {
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_storage);
18 |
19 | ToastLess.$(this, "state:" + StorageLess.Sdcard.$ready());
20 |
21 | LogLess.$d("sdcard total:" + StorageLess.Sdcard.$total() + ", used:" + StorageLess.Sdcard.$used() + ", free:" + StorageLess.Sdcard.$free());
22 | LogLess.$d("phone total:" + StorageLess.Phone.$total() + ", used:" + StorageLess.Phone.$used() + ", free:" + StorageLess.Phone.$free());
23 |
24 | LogLess.$d("sdcard string total:" + StorageLess.Sdcard.$totalString(this)
25 | + ", used:" + StorageLess.Sdcard.$usedString(this)
26 | + ", free:" + StorageLess.Sdcard.$freeString(this));
27 |
28 | if (StorageLess.ExtSdcard.$path() != null) {
29 | LogLess.$d("extSdcard string total:" + Formatter.formatFileSize(this, StorageLess.ExtSdcard.$total())
30 | + ", used:" + Formatter.formatFileSize(this, StorageLess.ExtSdcard.$used())
31 | + ", free:" + Formatter.formatFileSize(this, StorageLess.ExtSdcard.$free()));
32 | } else {
33 | LogLess.$d("no extSdcard.");
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/ToastActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.jayfeng.lesscode.app.R;
7 | import com.jayfeng.lesscode.core.ToastLess;
8 |
9 | public class ToastActivity extends Activity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_toast);
15 |
16 |
17 | ToastLess.$("xxxxx");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/activity/ViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.Button;
7 |
8 | import com.jayfeng.lesscode.app.R;
9 | import com.jayfeng.lesscode.core.LogLess;
10 | import com.jayfeng.lesscode.core.ViewLess;
11 | import com.jayfeng.lesscode.core.other.ViewThrottleClickListener;
12 |
13 | public class ViewActivity extends Activity {
14 |
15 | private Button normalButton;
16 | private Button throttleButton;
17 | private Button throttleLongButton;
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_view);
23 |
24 | normalButton = ViewLess.$(this, R.id.button_normal);
25 | throttleButton = ViewLess.$(this, R.id.button_throttle);
26 | throttleLongButton = ViewLess.$(this, R.id.button_throttle_long);
27 |
28 | normalButton.setOnClickListener(new View.OnClickListener() {
29 | @Override
30 | public void onClick(View v) {
31 | LogLess.$d("normal button click");
32 | }
33 | });
34 | throttleButton.setOnClickListener(new ViewThrottleClickListener() {
35 | @Override
36 | public void throttleClick(View view) {
37 | LogLess.$d("throttle click");
38 | }
39 | });
40 | throttleLongButton.setOnClickListener(new ViewThrottleClickListener() {
41 | @Override
42 | public void throttleClick(View view) {
43 | LogLess.$d("throttle click 3s");
44 | }
45 |
46 | @Override
47 | public long getThrottleTime() {
48 | return 3000;
49 | }
50 | });
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/model/LessItem.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.model;
2 |
3 | public class LessItem {
4 |
5 | private String name;
6 | private String className;
7 |
8 | public String getName() {
9 | return name;
10 | }
11 |
12 | public void setName(String name) {
13 | this.name = name;
14 | }
15 |
16 | public String getClassName() {
17 | return className;
18 | }
19 |
20 | public void setClassName(String className) {
21 | this.className = className;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jayfeng/lesscode/app/model/Person.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.app.model;
2 |
3 | import java.io.Serializable;
4 |
5 | public class Person implements Serializable {
6 |
7 | private String name;
8 |
9 | public Person(String name) {
10 | this.name = name;
11 | }
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | public void setName(String name) {
18 | this.name = name;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/girl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/app/src/main/res/drawable-xhdpi/girl.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/girl2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/app/src/main/res/drawable-xhdpi/girl2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/xinru.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/app/src/main/res/drawable-xhdpi/xinru.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/list_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/list_divider_p.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/list_item_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 | -
8 |
9 |
10 | -
11 |
12 |
13 | -
14 |
15 |
16 | -
17 |
18 |
19 | -
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_activity.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_adapter.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_adapter_base.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_adapter_pager.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_adapter_recycler.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_app.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
20 |
21 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_bitmap.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_cache.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_device.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_display.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
15 |
16 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_drawable.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
15 |
16 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_encode.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_file.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_http.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_keyborad.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
21 |
22 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_log.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_list_item.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_network.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_resource.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
13 |
14 |
20 |
21 |
31 |
32 |
33 |
39 |
40 |
46 |
47 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_shared_preference.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_storage.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_toast.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_update.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_view.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
17 |
18 |
19 |
23 |
24 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/adapter_list_item_header.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #fff
4 | #eee
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | LessCode Sample
5 | Hello world!
6 | LessCode Sample
7 | Settings
8 | LogActivity
9 | StorageActivity
10 | AdapterActivity
11 | BaseAdapterActivity
12 | PagerAdapterActivity
13 | RecyclerAdapterActivity
14 | UpdateActivity
15 | ActivityActivity
16 | CacheActivity
17 | DeviceActivity
18 | DisplayActivity
19 | EncodeActivity
20 | FileActivity
21 | HttpActivity
22 | KeyboradActivity
23 | NetworkActivity
24 | ResourceActivity
25 | SharedPreferenceActivity
26 | ToastActivity
27 | ViewActivity
28 | AppActivity
29 | DrawableActivity
30 | BitmapActivity
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | google()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.0.1'
10 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'
11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | jcenter()
20 | google()
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openproject/LessCode/a4829f8643bcd6b22eae1bd625a4bc7597b052d7/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Mar 28 16:07:08 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lesscode-core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lesscode-core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.github.dcendents.android-maven'
3 | apply plugin: 'com.jfrog.bintray'
4 |
5 | version = "2.4.2" // #CONFIG# // project version
6 |
7 | android {
8 | compileSdkVersion 27
9 | buildToolsVersion "27.0.2"
10 | // resourcePrefix "less_" // #CONFIG# // please remove this if you don't known it
11 | defaultConfig {
12 | minSdkVersion 14
13 | targetSdkVersion 27
14 | versionCode 1
15 | versionName "1.0"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 |
24 | lintOptions {
25 | abortOnError false
26 | }
27 | }
28 |
29 | dependencies {
30 | compile fileTree(dir: 'libs', include: ['*.jar'])
31 | compile 'com.android.support:support-v4:27.0.2'
32 | compile 'com.android.support:recyclerview-v7:27.0.2'
33 | }
34 |
35 | def siteUrl = 'https://github.com/openproject/LessCode' // #CONFIG# // project homepage
36 | def gitUrl = 'https://github.com/openproject/LessCode.git' // #CONFIG# // project git
37 | group = "com.jayfeng" // #CONFIG# // Maven Group ID for the artifact (pageckage name is ok)
38 |
39 | install {
40 | repositories.mavenInstaller {
41 | // This generates POM.xml with proper parameters
42 | pom {
43 | project {
44 | packaging 'aar'
45 | name 'Less Code For Android' // #CONFIG# // project title
46 | url siteUrl
47 | // Set your license
48 | licenses {
49 | license {
50 | name 'The Apache Software License, Version 2.0'
51 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
52 | }
53 | }
54 | developers {
55 | developer {
56 | id 'jayfeng' // #CONFIG# // your user id (you can write your nickname)
57 | name 'jian.feng' // #CONFIG# // your user name
58 | email '673592063@qq.com' // #CONFIG# // your email
59 | }
60 | }
61 | scm {
62 | connection gitUrl
63 | developerConnection gitUrl
64 | url siteUrl
65 | }
66 | }
67 | }
68 | }
69 | }
70 |
71 | task sourcesJar(type: Jar) {
72 | from android.sourceSets.main.java.srcDirs
73 | classifier = 'sources'
74 | }
75 |
76 | task javadoc(type: Javadoc) {
77 | source = android.sourceSets.main.java.srcDirs
78 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
79 | }
80 |
81 | task javadocJar(type: Jar, dependsOn: javadoc) {
82 | classifier = 'javadoc'
83 | from javadoc.destinationDir
84 | }
85 |
86 | artifacts {
87 | // archives javadocJar
88 | archives sourcesJar
89 | }
90 |
91 | Properties properties = new Properties()
92 | boolean isHasFile = false
93 | if (project.rootProject.file('local.properties') != null){
94 | isHasFile = true
95 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
96 | }
97 | bintray {
98 | user = isHasFile ? properties.getProperty("bintray.user") : System.getenv("bintray.user")
99 | key = isHasFile ? properties.getProperty("bintray.apikey") : System.getenv("bintray.apikey")
100 | configurations = ['archives']
101 | pkg {
102 | repo = "maven"
103 | name = "lesscode" // #CONFIG# project name in jcenter
104 | websiteUrl = siteUrl
105 | vcsUrl = gitUrl
106 | licenses = ["Apache-2.0"]
107 | publish = true
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/lesscode-core/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 /home/jay/tools/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 | #-keepattributes Exceptions,InnerClasses
16 | # keep public class
17 | #-dontwarn com.jayfeng.lesscode.core.*
18 | #-keep public class com.jayfeng.lesscode.core.*
19 | #-keep public class *$*
20 | # keep public member
21 | #-keepclassmembers class com.jayfeng.lesscode.core.* {
22 | # public *;
23 | }
24 | #-keepclassmembers class com.jayfeng.lesscode.core.*$* {
25 | # public *;
26 | #}
27 | # keep and reflect
28 | #-keepattributes Signature
29 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/$.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 |
5 | public final class $ {
6 | /**
7 | * 单例
8 | */
9 | private volatile static $ instance;
10 | public static $ getInstance() {
11 | if (instance == null) {
12 | synchronized ($.class) {
13 | if (instance == null) {
14 | instance = new $();
15 | }
16 | }
17 | }
18 | return instance;
19 | }
20 |
21 | /**
22 | * 名义上为build,实则是检查一些必须配置的变量
23 | */
24 | public void build(){
25 | if (sAppContext == null) {
26 | throw new RuntimeException("please config the lesscode application context");
27 | }
28 | }
29 |
30 | /**
31 | * *********************************************************************************************
32 | * Global ApplicationContext
33 | * *********************************************************************************************
34 | */
35 | static Context sAppContext;
36 | public $ context(Context context) {
37 | sAppContext = context;
38 | return this;
39 | }
40 |
41 | /**
42 | * *********************************************************************************************
43 | * AppLess
44 | * *********************************************************************************************
45 | */
46 | public static final String KEY_DOWNLOAD_URL = "download_url";
47 | static String sUpdateJsonUrl;
48 | public $ app(String updateJsonUrl) {
49 | sUpdateJsonUrl = updateJsonUrl;
50 | return this;
51 | }
52 |
53 | /**
54 | * *********************************************************************************************
55 | * UpdateLess
56 | * *********************************************************************************************
57 | */
58 | static int sNotificationFrequent = 5;
59 | static String sDownloadSDPath;
60 | static int sUpdateIcon;
61 | @Deprecated
62 | public $ update(String downloadSDPath, int notificationFrequent) {
63 | sNotificationFrequent = notificationFrequent;
64 | sDownloadSDPath = downloadSDPath;
65 | return this;
66 | }
67 |
68 | public $ update(String downloadSDPath, int notificationFrequent, int updateIcon) {
69 | sNotificationFrequent = notificationFrequent;
70 | sDownloadSDPath = downloadSDPath;
71 | sUpdateIcon = updateIcon;
72 | return this;
73 | }
74 |
75 | /**
76 | * *********************************************************************************************
77 | * HttpLess
78 | * *********************************************************************************************
79 | */
80 | static int sConnectTimeOut = 5000;
81 | static int sReadTimeout = 5000;
82 | public $ http(int connectTimeOut, int readTimeout) {
83 | sConnectTimeOut = connectTimeOut;
84 | sReadTimeout = readTimeout;
85 | return this;
86 | }
87 |
88 | /**
89 | * *********************************************************************************************
90 | * LogLess
91 | * *********************************************************************************************
92 | */
93 | static boolean sDebug;
94 | static String sTAG;
95 | public $ log(boolean debug, String tag) {
96 | sDebug = debug;
97 | sTAG = tag;
98 | return this;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/ActivityLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 | import android.view.WindowManager;
6 |
7 | public final class ActivityLess {
8 |
9 | /**
10 | * 第一次和第二次的退出间隔时间基准
11 | */
12 | private static final long EXIT_TWICE_INTERVAL = 2000;
13 |
14 | private static long mExitTime = 0;
15 |
16 | /**
17 | * 设置Activity无标题
18 | * @param activity
19 | */
20 | public static void $noTitle(Activity activity) {
21 | activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
22 | }
23 |
24 | /**
25 | * 设置Activity全屏
26 | * @param activity
27 | */
28 | public static void $fullScreen(Activity activity) {
29 | $fullScreen(activity, true);
30 | }
31 |
32 | /**
33 | * 根据参数设置Activity是否全屏
34 | * @param activity
35 | * @param fullScreen
36 | */
37 | public static void $fullScreen(Activity activity, boolean fullScreen) {
38 | if (fullScreen) {
39 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
40 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
41 | WindowManager.LayoutParams.FLAG_FULLSCREEN);
42 | } else {
43 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
44 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
45 | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
46 | }
47 |
48 | }
49 |
50 | /**
51 | * 第二次按退出则返回true,否则返回false
52 | * @return
53 | */
54 | public static boolean $exitTwice() {
55 | long newExitTime = System.currentTimeMillis();
56 | if (newExitTime - mExitTime > EXIT_TWICE_INTERVAL) {
57 | mExitTime = newExitTime;
58 | return false;
59 | } else {
60 | return true;
61 | }
62 | }
63 |
64 | /**
65 | * 优化activity的背景过度绘制
66 | * 在合适的时候调用,建议放在super.onCreate(saveInstanceState)代码下面一行
67 | * @param activity
68 | */
69 | public static void $optimizeBackgroundOverdraw(Activity activity) {
70 | activity.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/AlarmLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.app.AlarmManager;
4 | import android.app.PendingIntent;
5 | import android.content.Context;
6 | import android.content.Intent;
7 |
8 | public final class AlarmLess {
9 |
10 | /**
11 | * 开启定时器
12 | * @param context
13 | * @param triggerAtMillis
14 | * @param pendingIntent
15 | */
16 | public static void $startIntent(Context context, int triggerAtMillis, PendingIntent pendingIntent) {
17 | AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
18 | manager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
19 | }
20 |
21 | /**
22 | * 停止定时器
23 | * @param context
24 | * @param pendingIntent
25 | */
26 | public static void $stop(Context context, PendingIntent pendingIntent) {
27 | AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
28 | manager.cancel(pendingIntent);
29 | }
30 |
31 | /**
32 | * 开启轮询闹钟
33 | * @param context
34 | * @param triggerAtMillis
35 | * @param cls
36 | * @param action
37 | */
38 | public static void $startAction(Context context, int triggerAtMillis, Class> cls, String action) {
39 | Intent intent = new Intent(context, cls);
40 | intent.setAction(action);
41 | PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
42 | $startIntent(context, triggerAtMillis, pendingIntent);
43 | }
44 |
45 | /**
46 | * 停止轮询闹钟
47 | * @param context
48 | * @param cls
49 | * @param action
50 | */
51 | public static void $stop(Context context, Class> cls, String action) {
52 | Intent intent = new Intent(context, cls);
53 | intent.setAction(action);
54 | PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
55 | $stop(context, pendingIntent);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/AppLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.app.ActivityManager;
4 | import android.content.Context;
5 | import android.content.pm.ApplicationInfo;
6 | import android.content.pm.PackageInfo;
7 | import android.content.pm.PackageManager;
8 | import android.content.pm.Signature;
9 |
10 | import java.io.File;
11 | import java.util.List;
12 |
13 | public final class AppLess {
14 |
15 | /**
16 | * 获取app的版本数versionCode,比如38
17 | * @return
18 | */
19 | public static int $vercode() {
20 | int result = 0;
21 | String packageName = $.sAppContext.getPackageName();
22 | PackageInfo packageInfo;
23 | try {
24 | packageInfo = $.sAppContext.getPackageManager().getPackageInfo(packageName, 0);
25 | result = packageInfo.versionCode;
26 | } catch (PackageManager.NameNotFoundException e) {
27 | throw new AssertionError(e);
28 | }
29 | return result;
30 | }
31 |
32 | /**
33 | * 获取app的版本名versionName,比如0.6.9
34 | * @return
35 | */
36 | public static String $vername() {
37 | String result = null;
38 | String packageName = $.sAppContext.getPackageName();
39 | PackageInfo packageInfo;
40 | try {
41 | packageInfo = $.sAppContext.getPackageManager().getPackageInfo(packageName, 0);
42 | result = packageInfo.versionName;
43 | } catch (PackageManager.NameNotFoundException e) {
44 | throw new AssertionError(e);
45 | }
46 | return result;
47 | }
48 |
49 | /**
50 | * 获取app的名称
51 | * @return
52 | */
53 | public static String $appname() {
54 | String result = null;
55 | String packageName = $.sAppContext.getPackageName();
56 | ApplicationInfo applicationInfo;
57 | try {
58 | PackageManager packageManager = $.sAppContext.getPackageManager();
59 | applicationInfo = packageManager.getApplicationInfo(packageName, 0);
60 | result = packageManager.getApplicationLabel(applicationInfo).toString();
61 | } catch (PackageManager.NameNotFoundException e) {
62 | throw new AssertionError(e);
63 | } catch (Exception e) {
64 | e.printStackTrace();
65 | }
66 | return result;
67 | }
68 |
69 | /**
70 | * 判断一个app是否在运行
71 | * @param packageName app的包名
72 | * @return 在运行则返回true,否则false
73 | */
74 | public static boolean $running(String packageName) {
75 | if (packageName == null) {
76 | packageName = $.sAppContext.getPackageName();
77 | }
78 | ActivityManager am = (ActivityManager) $.sAppContext.getSystemService(Context.ACTIVITY_SERVICE);
79 | List infos = am.getRunningAppProcesses();
80 | for(ActivityManager.RunningAppProcessInfo rapi : infos){
81 | if(rapi.processName.equals(packageName))
82 | return true;
83 | }
84 | return false;
85 | }
86 |
87 | /**
88 | * 判断一个activity是否在前台运行
89 | * @param activityName activity的全路径名称
90 | * @return 在前台则返回true,否则返回false
91 | */
92 | public static boolean isTopActivy(String activityName) {
93 | ActivityManager manager = (ActivityManager) $.sAppContext.getSystemService(Context.ACTIVITY_SERVICE);
94 | List runningTaskInfos = manager.getRunningTasks(1);
95 | String cmpNameTemp = null;
96 |
97 | if (runningTaskInfos != null) {
98 | cmpNameTemp = runningTaskInfos.get(0).topActivity.getShortClassName();
99 | }
100 |
101 | if (cmpNameTemp == null) {
102 | return false;
103 | }
104 | return cmpNameTemp.endsWith(activityName);
105 | }
106 |
107 | /**
108 | * 获取应用公钥签名
109 | * @param context
110 | * @return
111 | */
112 | public static Signature $sign(Context context) {
113 | PackageInfo pi;
114 | Signature sign = null;
115 | try {
116 | pi = context.getPackageManager().getPackageInfo(
117 | context.getPackageName(), PackageManager.GET_SIGNATURES);
118 | sign = pi.signatures[0];
119 | } catch (Exception e) {
120 | e.printStackTrace();
121 | }
122 | return sign;
123 | }
124 |
125 | /**
126 | * 比较当前签名HashCode和预设的HashCode
127 | * @param context
128 | * @param presetHashCode
129 | * @return
130 | */
131 | public static boolean $signCheckWithHashCode(Context context, int presetHashCode) {
132 | Signature signature = $sign(context);
133 | return signature.hashCode() == presetHashCode;
134 | }
135 |
136 | /**
137 | * 删除应用数据: cache, file, share prefs, databases
138 | * @param context
139 | */
140 | public static void $clear(Context context) {
141 | $clearCache(context);
142 | $clearFiles(context);
143 | $clearSharedPreference(context);
144 | $clearDatabase(context);
145 | }
146 |
147 | /**
148 | * 删除应用缓存目录
149 | * @param context
150 | */
151 | public static void $clearCache(Context context) {
152 | FileLess.$del(context.getCacheDir(), true);
153 | FileLess.$del(context.getExternalCacheDir(), true);
154 | }
155 |
156 | /**
157 | * 删除应用文件目录
158 | * @param context
159 | */
160 | public static void $clearFiles(Context context) {
161 | FileLess.$del(context.getFilesDir(), true);
162 | }
163 |
164 | /**
165 | * 删除应用Shared Prefrence目录
166 | * @param context
167 | */
168 | public static void $clearSharedPreference(Context context) {
169 | FileLess.$del(new File("/data/data/" + context.getPackageName() + "/shared_prefs"), true);
170 | }
171 |
172 | /**
173 | * 删除应用数据库目录
174 | * @param context
175 | */
176 | public static void $clearDatabase(Context context) {
177 | FileLess.$del(new File("/data/data/" + context.getPackageName() + "/databases"), true);
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/ApplicationLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.app.ActivityManager;
4 | import android.content.Context;
5 | import android.os.Process;
6 |
7 | import java.util.List;
8 |
9 | public final class ApplicationLess {
10 |
11 | /**
12 | * 根据进程名称判断第一次真正的初始化
13 | *
14 | * @param context
15 | * @return
16 | */
17 | public static boolean $init(Context context) {
18 | ActivityManager am = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE));
19 | List processInfos = am.getRunningAppProcesses();
20 | String mainProcessName = context.getPackageName();
21 | int myPid = Process.myPid();
22 | for (ActivityManager.RunningAppProcessInfo info : processInfos) {
23 | if (info.pid == myPid && mainProcessName.equals(info.processName)) {
24 | return true;
25 | }
26 | }
27 | return false;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/BitmapLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.ColorMatrix;
9 | import android.graphics.ColorMatrixColorFilter;
10 | import android.graphics.Matrix;
11 | import android.graphics.Paint;
12 | import android.graphics.PorterDuff;
13 | import android.graphics.PorterDuffXfermode;
14 | import android.graphics.Rect;
15 | import android.graphics.RectF;
16 | import android.os.Environment;
17 |
18 | import java.io.File;
19 | import java.io.FileNotFoundException;
20 | import java.io.FileOutputStream;
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 | import java.util.UUID;
24 |
25 | public final class BitmapLess {
26 |
27 | /**
28 | * 根据reqWidth, reqHeight计算最合适的inSampleSize
29 | *
30 | * @param options
31 | * @param maxWidth
32 | * @param maxHeight
33 | * @return
34 | */
35 | public static int $sampleSize(BitmapFactory.Options options, int maxWidth, int maxHeight) {
36 | // raw height and width of image
37 | int rawWidth = options.outWidth;
38 | int rawHeight = options.outHeight;
39 |
40 | // calculate best sample size
41 | int inSampleSize = 0;
42 | if (rawHeight > maxHeight || rawWidth > maxWidth) {
43 | float ratioWidth = (float) rawWidth / maxWidth;
44 | float ratioHeight = (float) rawHeight / maxHeight;
45 | inSampleSize = (int) Math.min(ratioHeight, ratioWidth);
46 | }
47 | inSampleSize = Math.max(1, inSampleSize);
48 |
49 | return inSampleSize;
50 | }
51 |
52 | /**
53 | * 更节省内存的读取raw资源成Bitmap
54 | *
55 | * @param context
56 | * @param rawId
57 | * @return
58 | */
59 | public static Bitmap $raw(Context context, int rawId) {
60 | BitmapFactory.Options opt = new BitmapFactory.Options();
61 | opt.inPreferredConfig = Bitmap.Config.RGB_565;
62 | opt.inPurgeable = true;
63 | opt.inInputShareable = true;
64 | InputStream is = context.getResources().openRawResource(rawId);
65 | return BitmapFactory.decodeStream(is, null, opt);
66 | }
67 |
68 | /**
69 | * 旋转Bitmap(默认回收传进来的原始Bitmap)
70 | *
71 | * @param originBitmap
72 | * @param angle
73 | * @return
74 | */
75 | public static Bitmap $rotate(Bitmap originBitmap, int angle) {
76 | return $rotate(originBitmap, angle, true);
77 | }
78 |
79 | /**
80 | * 旋转Bitmap
81 | *
82 | * @param angle
83 | * @param originBitmap
84 | * @param recycle 是否回收传进来的原始Bitmap
85 | * @return
86 | */
87 | public static Bitmap $rotate(Bitmap originBitmap, int angle, boolean recycle) {
88 | Matrix matrix = new Matrix();
89 | matrix.postRotate(angle);
90 | Bitmap rotatedBitmap = Bitmap.createBitmap(originBitmap,
91 | 0, 0, originBitmap.getWidth(), originBitmap.getHeight(), matrix, true);
92 | if (recycle && originBitmap != null && !originBitmap.isRecycled()) {
93 | originBitmap.recycle();
94 | }
95 | return rotatedBitmap;
96 | }
97 |
98 | /**
99 | * 缩放Bitmap(默认回收传进来的原始Bitmap)
100 | *
101 | * @param originBitmap
102 | * @param scaleX
103 | * @param scaleY
104 | * @return
105 | */
106 | public static Bitmap $scale(Bitmap originBitmap, float scaleX, float scaleY) {
107 | return $scale(originBitmap, scaleX, scaleY, true);
108 | }
109 |
110 | /**
111 | * 缩放Bitmap - 按缩放倍数
112 | *
113 | * @param originBitmap
114 | * @param scaleX
115 | * @param scaleY
116 | * @param recycle 是否回收传进来的原始Bitmap
117 | * @return
118 | */
119 | public static Bitmap $scale(Bitmap originBitmap, float scaleX, float scaleY, boolean recycle) {
120 | Matrix matrix = new Matrix();
121 | matrix.postScale(scaleX, scaleY);
122 | Bitmap scaledBitmap = Bitmap.createBitmap(originBitmap,
123 | 0, 0, originBitmap.getWidth(), originBitmap.getHeight(), matrix, true);
124 | if (recycle && originBitmap != null && !originBitmap.isRecycled()) {
125 | originBitmap.recycle();
126 | }
127 | return scaledBitmap;
128 | }
129 |
130 | /**
131 | * 缩放Bitmap - 缩放到目标大小
132 | *
133 | * @param originBitmap
134 | * @param dstWidth
135 | * @param dstHeight
136 | * @param recycle 是否回收传进来的原始Bitmap
137 | * @return
138 | */
139 | public static Bitmap $scale(Bitmap originBitmap, int dstWidth, int dstHeight, boolean recycle) {
140 | Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap, dstWidth, dstHeight, true);
141 | if (recycle && originBitmap != null && !originBitmap.isRecycled()) {
142 | originBitmap.recycle();
143 | }
144 | return scaledBitmap;
145 | }
146 |
147 | /**
148 | * 获取缩略图(默认关闭自动旋转)
149 | *
150 | * @param path
151 | * @param maxWidth
152 | * @param maxHeight
153 | * @return
154 | */
155 | public static Bitmap $thumbnail(String path, int maxWidth, int maxHeight) {
156 | return $thumbnail(path, maxWidth, maxHeight, false);
157 | }
158 |
159 | /**
160 | * 获取缩略图
161 | * 1. 支持自动旋转
162 | *
163 | * @param path
164 | * @param maxWidth
165 | * @param maxHeight
166 | * @param autoRotate
167 | * @return
168 | */
169 | public static Bitmap $thumbnail(String path, int maxWidth, int maxHeight, boolean autoRotate) {
170 |
171 | int angle = 0;
172 | if (autoRotate) {
173 | angle = ImageLess.$exifRotateAngle(path);
174 | }
175 |
176 | BitmapFactory.Options options = new BitmapFactory.Options();
177 | options.inJustDecodeBounds = true;
178 | // 获取这个图片的宽和高, 此时返回bm为空
179 | Bitmap bitmap = BitmapFactory.decodeFile(path, options);
180 | options.inJustDecodeBounds = false;
181 | // 计算缩放比
182 | int sampleSize = $sampleSize(options, maxWidth, maxHeight);
183 | options.inSampleSize = sampleSize;
184 | options.inPreferredConfig = Bitmap.Config.RGB_565;
185 | options.inPurgeable = true;
186 | options.inInputShareable = true;
187 |
188 | if (bitmap != null && !bitmap.isRecycled()) {
189 | bitmap.recycle();
190 | }
191 | bitmap = BitmapFactory.decodeFile(path, options);
192 |
193 | if (autoRotate && angle != 0) {
194 | bitmap = $rotate(bitmap, angle);
195 | }
196 |
197 | return bitmap;
198 | }
199 |
200 | /**
201 | * 保存到本地,默认路径/mnt/sdcard/[package]/save/
202 | *
203 | * @param bitmap
204 | * @param format
205 | * @param quality
206 | * @param context
207 | * @return
208 | */
209 | public static String $save(Bitmap bitmap, Bitmap.CompressFormat format, int quality, Context context) {
210 | if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
211 | return null;
212 | }
213 |
214 | File dir = new File(Environment.getExternalStorageDirectory() + "/" + context.getPackageName() + "/save/");
215 | if (!dir.exists()) {
216 | dir.mkdirs();
217 | }
218 | File destFile = new File(dir, UUID.randomUUID().toString());
219 | return $save(bitmap, format, quality, destFile);
220 | }
221 |
222 | /**
223 | * 保存到本地destFile
224 | *
225 | * @param bitmap
226 | * @param format
227 | * @param quality
228 | * @param destFile
229 | * @return
230 | */
231 | public static String $save(Bitmap bitmap, Bitmap.CompressFormat format, int quality, File destFile) {
232 | try {
233 | FileOutputStream out = new FileOutputStream(destFile);
234 | if (bitmap.compress(format, quality, out)) {
235 | out.flush();
236 | out.close();
237 | }
238 |
239 | if (bitmap != null && !bitmap.isRecycled()) {
240 | bitmap.recycle();
241 | }
242 |
243 | return destFile.getAbsolutePath();
244 | } catch (FileNotFoundException e) {
245 | e.printStackTrace();
246 | } catch (IOException e) {
247 | e.printStackTrace();
248 | }
249 | return null;
250 | }
251 |
252 | /**
253 | * 圆角Bitmap
254 | *
255 | * @param originBitmap
256 | * @param radius
257 | * @param recycle
258 | * @return
259 | */
260 | public static Bitmap $round(Bitmap originBitmap, int radius, boolean recycle) {
261 | // 准备画笔
262 | Paint paint = new Paint();
263 | paint.setAntiAlias(true);
264 |
265 | // 准备裁剪的矩阵
266 | Rect rect = new Rect(0, 0, originBitmap.getWidth(), originBitmap.getHeight());
267 | RectF rectF = new RectF(new Rect(0, 0, originBitmap.getWidth(), originBitmap.getHeight()));
268 |
269 | Bitmap roundBitmap = Bitmap.createBitmap(originBitmap.getWidth(), originBitmap.getHeight(), Bitmap.Config.ARGB_8888);
270 | Canvas canvas = new Canvas(roundBitmap);
271 | canvas.drawRoundRect(rectF, radius, radius, paint);
272 |
273 | // 这一句是核心,关于Xfermode和SRC_IN请自行查阅
274 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
275 | canvas.drawBitmap(originBitmap, rect, rect, paint);
276 |
277 | // 是否回收原始Bitmap
278 | if (recycle && originBitmap != null && !originBitmap.isRecycled()) {
279 | originBitmap.recycle();
280 | }
281 |
282 | return roundBitmap;
283 | }
284 |
285 | /**
286 | * 圆形Bitmap:居中裁剪
287 | *
288 | * @param originBitmap
289 | * @param recycle
290 | * @return
291 | */
292 | public static Bitmap $circle(Bitmap originBitmap, boolean recycle) {
293 | int min = originBitmap.getWidth() > originBitmap.getHeight() ? originBitmap.getHeight() : originBitmap.getWidth();
294 | Paint paint = new Paint();
295 | paint.setAntiAlias(true);
296 | Bitmap circleBitmap = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);
297 | Canvas canvas = new Canvas(circleBitmap);
298 | canvas.drawCircle(min / 2, min / 2, min / 2, paint);
299 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
300 |
301 | // 居中显示
302 | int left = - (originBitmap.getWidth() - min) / 2;
303 | int top = - (originBitmap.getHeight() - min) / 2;
304 | canvas.drawBitmap(originBitmap, left, top, paint);
305 |
306 | // 是否回收原始Bitmap
307 | if (recycle && originBitmap != null && !originBitmap.isRecycled()) {
308 | originBitmap.recycle();
309 | }
310 |
311 | return circleBitmap;
312 | }
313 |
314 | /**
315 | * 灰阶效果
316 | * @param originBitmap
317 | * @param recycle
318 | * @return
319 | */
320 | public static Bitmap $gray(Bitmap originBitmap, boolean recycle) {
321 | Bitmap grayBitmap = Bitmap.createBitmap(originBitmap.getWidth(),
322 | originBitmap.getHeight(), Bitmap.Config.RGB_565);
323 | Canvas canvas = new Canvas(grayBitmap);
324 | Paint paint = new Paint();
325 | ColorMatrix colorMatrix = new ColorMatrix();
326 | colorMatrix.setSaturation(0);
327 | ColorMatrixColorFilter colorMatrixColorFilter =
328 | new ColorMatrixColorFilter(colorMatrix);
329 | paint.setColorFilter(colorMatrixColorFilter);
330 | canvas.drawBitmap(originBitmap, 0, 0, paint);
331 |
332 | // 是否回收原始Bitmap
333 | if (recycle && originBitmap != null && !originBitmap.isRecycled()) {
334 | originBitmap.recycle();
335 | }
336 |
337 | return grayBitmap;
338 | }
339 | }
340 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/CacheLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | /**
7 | * 缓存相关的工具类
8 | * 常用于缓存网络请求返回的json保存到本地的缓存策略
9 | */
10 | public final class CacheLess {
11 |
12 | /**
13 | * 根据key查找缓存的内容
14 | * @param key
15 | * @param expireTime
16 | * @return
17 | */
18 | public static String $get(String key, long expireTime) {
19 | String result = null;
20 |
21 | File cacheDir = $.sAppContext.getCacheDir();
22 | if (StorageLess.Sdcard.$ready()) {
23 | cacheDir = $.sAppContext.getExternalCacheDir();
24 | }
25 |
26 | File file = new File(cacheDir, EncodeLess.$md5(key));
27 | if (file.exists() && file.isFile()) {
28 | long storageTime = System.currentTimeMillis() - file.lastModified();
29 |
30 | boolean online = NetworkLess.$online();
31 |
32 | // 如果系统时间不对(被调回很久之前),storageTime和expireTime的比较就没有意义了
33 | // 在这种情况下,如果有网就请求新内容,否则才考虑缓存
34 | if (online && storageTime < 0) {
35 | return null;
36 | }
37 | // 如果有网的情况下,且缓存已经过期,则返回null
38 | // 在无网的情况下, 即使过期也返回缓存
39 | if (online && storageTime > expireTime) {
40 | return null;
41 | }
42 | try {
43 | result = FileLess.$read(file);
44 | } catch (IOException e) {
45 | e.printStackTrace();
46 | }
47 | }
48 | return result;
49 | }
50 |
51 | /**
52 | * 设置字符串为特定key的缓存,保存到本地
53 | * @param key
54 | * @param data
55 | */
56 | public static void $set(String key, String data) {
57 | File cacheDir = $.sAppContext.getCacheDir();
58 | if (StorageLess.Sdcard.$ready()) {
59 | cacheDir = $.sAppContext.getExternalCacheDir();
60 | }
61 | if (!cacheDir.exists()) {
62 | cacheDir.mkdirs();
63 | }
64 | File file = new File(cacheDir, EncodeLess.$md5(key));
65 | try {
66 | FileLess.$write(file, data);
67 | } catch (IOException e) {
68 | e.printStackTrace();
69 | } catch (Exception e) {
70 | e.printStackTrace();
71 | }
72 |
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/DeviceLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.net.wifi.WifiInfo;
5 | import android.net.wifi.WifiManager;
6 | import android.text.TextUtils;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.IOException;
11 |
12 | /**
13 | * 设备相关的工具类
14 | */
15 | public final class DeviceLess {
16 |
17 | /**
18 | * 获取设备的mac地址
19 | * 这里要特别说明一下,mac地址不是一定能获取的到的,你可能要更优先使用设备ID
20 | * @return mac地址
21 | */
22 | public static String $mac() {
23 |
24 | String result = null;
25 | try {
26 | String path = "sys/class/net/wlan0/address";
27 | if ((new File(path)).exists()) {
28 | FileInputStream fis = null;
29 | try {
30 | fis = new FileInputStream(path);
31 | byte[] buffer = new byte[8192];
32 | int byteCount = fis.read(buffer);
33 | if (byteCount > 0) {
34 | result = new String(buffer, 0, byteCount, "utf-8");
35 | }
36 | } catch (IOException e) {
37 | e.printStackTrace();
38 | } finally {
39 | if (fis != null) {
40 | fis.close();
41 | }
42 | }
43 |
44 | }
45 | if (TextUtils.isEmpty(result)) {
46 | path = "sys/class/net/eth0/address";
47 | FileInputStream fis_name = null;
48 | try {
49 | fis_name = new FileInputStream(path);
50 | byte[] buffer_name = new byte[8192];
51 | int byteCount_name = fis_name.read(buffer_name);
52 | if (byteCount_name > 0) {
53 | result = new String(buffer_name, 0, byteCount_name, "utf-8");
54 | }
55 | } catch (IOException e) {
56 | e.printStackTrace();
57 | } finally {
58 | if (fis_name != null) {
59 | fis_name.close();
60 | }
61 | }
62 |
63 | }
64 |
65 | if (TextUtils.isEmpty(result)) {
66 | WifiManager wifi = (WifiManager) $.sAppContext.getSystemService(Context.WIFI_SERVICE);
67 | WifiInfo wifiInfo = wifi.getConnectionInfo();
68 | result = wifiInfo.getMacAddress();
69 | }
70 |
71 | } catch (Exception e) {
72 | e.printStackTrace();
73 | }
74 |
75 | return result;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/DisplayLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.res.Configuration;
6 | import android.content.res.Resources;
7 | import android.graphics.Bitmap;
8 | import android.graphics.Rect;
9 | import android.util.DisplayMetrics;
10 | import android.view.Window;
11 | import android.view.WindowManager;
12 |
13 | import java.lang.reflect.Field;
14 |
15 | /**
16 | * 屏幕显示相关的工具类
17 | */
18 | public final class DisplayLess {
19 |
20 | /**
21 | * 屏幕宽度
22 | *
23 | * @param context
24 | * @return
25 | */
26 | public static int $width(Context context) {
27 | DisplayMetrics displayMetrics = new DisplayMetrics();
28 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
29 | windowManager.getDefaultDisplay().getMetrics(displayMetrics);
30 | return displayMetrics.widthPixels;
31 | }
32 |
33 | /**
34 | * 屏幕高度
35 | *
36 | * @param context
37 | * @return
38 | */
39 | public static int $height(Context context) {
40 | DisplayMetrics displayMetrics = new DisplayMetrics();
41 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
42 | windowManager.getDefaultDisplay().getMetrics(displayMetrics);
43 | return displayMetrics.heightPixels;
44 | }
45 |
46 | /**
47 | * dp转px
48 | *
49 | * @param dp
50 | * @return
51 | */
52 | public static int $dp2px(float dp) {
53 | return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
54 | }
55 |
56 | /**
57 | * sp转px
58 | *
59 | * @param sp
60 | * @return
61 | */
62 | public static int $sp2px(float sp) {
63 | float scale = Resources.getSystem().getDisplayMetrics().scaledDensity;
64 | return (int) (sp * scale + 0.5f);
65 | }
66 |
67 | /**
68 | * 获取状态栏高度
69 | * 注: 该方法在onCreate中获取值为0
70 | *
71 | * @param activity
72 | * @return
73 | */
74 | public static int $statusBarHeight(Activity activity) {
75 | Rect frame = new Rect();
76 | activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
77 | return frame.top;
78 | }
79 |
80 | /**
81 | * 获取状态栏高度
82 | * 注: 该方法在onCreate中获取值为0
83 | *
84 | * @param resources
85 | * @return
86 | */
87 | public static int $statusBarHeight(Resources resources) {
88 | Class> c = null;
89 | Object obj = null;
90 | Field field = null;
91 | int x = 0;
92 | int statusBarHeight = 0;
93 | try {
94 | c = Class.forName("com.android.internal.R$dimen");
95 | obj = c.newInstance();
96 | field = c.getField("status_bar_height");
97 | x = Integer.parseInt(field.get(obj).toString());
98 | statusBarHeight = resources.getDimensionPixelSize(x);
99 | } catch (Exception e) {
100 | e.printStackTrace();
101 | }
102 | return statusBarHeight;
103 | }
104 |
105 | /**
106 | * 获取标题栏高度
107 | *
108 | * @param activity
109 | * @return
110 | */
111 | public static int $titleBarHeight(Activity activity) {
112 | int contentTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
113 | int titleBarHeight = contentTop - $statusBarHeight(activity);
114 | return titleBarHeight;
115 | }
116 |
117 | /**
118 | * 是否为平板
119 | *
120 | * @param context
121 | * @return
122 | */
123 | public static boolean $tablet(Context context) {
124 | return (context.getResources().getConfiguration().screenLayout
125 | & Configuration.SCREENLAYOUT_SIZE_MASK)
126 | >=
127 | Configuration.SCREENLAYOUT_SIZE_LARGE;
128 | }
129 |
130 | /**
131 | * ****************************
132 | * 各大设备密度判断
133 | * ****************************
134 | */
135 | public static boolean $ldpi() {
136 | return $.sAppContext.getResources().getBoolean(R.bool.less_ldpi);
137 | }
138 |
139 | public static boolean $mdpi() {
140 | return $.sAppContext.getResources().getBoolean(R.bool.less_mdpi);
141 | }
142 |
143 | public static boolean $tvdpi() {
144 | return $.sAppContext.getResources().getBoolean(R.bool.less_tvdpi);
145 | }
146 |
147 | public static boolean $hdpi() {
148 | return $.sAppContext.getResources().getBoolean(R.bool.less_hdpi);
149 | }
150 |
151 | public static boolean $xhdpi() {
152 | return $.sAppContext.getResources().getBoolean(R.bool.less_xhdpi);
153 | }
154 |
155 | public static boolean $xxhdpi() {
156 | return $.sAppContext.getResources().getBoolean(R.bool.less_xxhdpi);
157 | }
158 |
159 | public static boolean $xxxhdpi() {
160 | return $.sAppContext.getResources().getBoolean(R.bool.less_xxxhdpi);
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/DrawableLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.res.ColorStateList;
4 | import android.graphics.PorterDuff;
5 | import android.graphics.drawable.Drawable;
6 | import android.support.v4.graphics.drawable.DrawableCompat;
7 |
8 | public final class DrawableLess {
9 |
10 |
11 | /**
12 | * ========================================================
13 | * tint drawable with Color or ColorStateList
14 | * using the DrawableCompat in support v4 library
15 | * ========================================================
16 | */
17 | public static Drawable $tint(Drawable originDrawable, int color) {
18 | return $tint(originDrawable, ColorStateList.valueOf(color));
19 | }
20 |
21 | public static Drawable $tint(Drawable originDrawable, int color, PorterDuff.Mode tintMode) {
22 | return $tint(originDrawable, ColorStateList.valueOf(color), tintMode);
23 | }
24 |
25 | public static Drawable $tint(Drawable originDrawable, ColorStateList colorStateList) {
26 | return $tint(originDrawable, colorStateList, null);
27 | }
28 |
29 | public static Drawable $tint(Drawable originDrawable, ColorStateList colorStateList, PorterDuff.Mode tintMode) {
30 | Drawable tintDrawable = DrawableCompat.wrap(originDrawable);
31 | if (tintMode != null) {
32 | DrawableCompat.setTintMode(tintDrawable, tintMode);
33 | }
34 | DrawableCompat.setTintList(tintDrawable, colorStateList);
35 | return tintDrawable;
36 | }
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/EncodeLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.security.MessageDigest;
5 | import java.security.NoSuchAlgorithmException;
6 |
7 | /**
8 | * 加解密相关的工具类
9 | */
10 | public final class EncodeLess {
11 |
12 | /**
13 | * 通用MD5加密
14 | * @param string
15 | * @return
16 | */
17 | public static String $md5(String string) {
18 | byte[] hash;
19 |
20 | try {
21 | hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
22 | } catch (NoSuchAlgorithmException e) {
23 | e.printStackTrace();
24 | return null;
25 | } catch (UnsupportedEncodingException e) {
26 | e.printStackTrace();
27 | return null;
28 | }
29 |
30 | StringBuilder hex = new StringBuilder(hash.length * 2);
31 | for (byte b : hash) {
32 | if ((b & 0xFF) < 0x10)
33 | hex.append("0");
34 | hex.append(Integer.toHexString(b & 0xFF));
35 | }
36 |
37 | return hex.toString();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/FileLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.DataOutputStream;
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.FileOutputStream;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.InputStreamReader;
11 | import java.util.zip.ZipEntry;
12 | import java.util.zip.ZipInputStream;
13 |
14 | /**
15 | * 文件操作相关的工具类
16 | */
17 | public final class FileLess {
18 |
19 | /**
20 | * 读取文件为字符串
21 | * @param file 文件
22 | * @return 文件内容字符串
23 | * @throws IOException
24 | */
25 | public static String $read(File file) throws IOException {
26 | String text = null;
27 | InputStream is = null;
28 | try {
29 | is = new FileInputStream(file);
30 | text = $read(is);
31 | } finally {
32 | if (is != null) {
33 | is.close();
34 | }
35 | }
36 | return text;
37 | }
38 |
39 | /**
40 | * 读取输入流为字符串,最常见的是网络请求
41 | * @param is 输入流
42 | * @return 输入流内容字符串
43 | * @throws IOException
44 | */
45 | public static String $read(InputStream is) throws IOException {
46 | StringBuffer strbuffer = new StringBuffer();
47 | String line;
48 | BufferedReader reader = null;
49 | try {
50 | reader = new BufferedReader(new InputStreamReader(is));
51 | while ((line = reader.readLine()) != null) {
52 | strbuffer.append(line).append("\r\n");
53 | }
54 | } finally {
55 | if (reader != null) {
56 | reader.close();
57 | }
58 | }
59 | return strbuffer.toString();
60 | }
61 |
62 | /**
63 | * 把字符串写入到文件中
64 | * @param file 被写入的目标文件
65 | * @param str 要写入的字符串内容
66 | * @throws IOException
67 | */
68 | public static void $write(File file, String str) throws IOException {
69 | DataOutputStream out = null;
70 | try {
71 | out = new DataOutputStream(new FileOutputStream(file));
72 | out.write(str.getBytes());
73 | } finally {
74 | if (out != null) {
75 | out.close();
76 | }
77 | }
78 | }
79 |
80 | /**
81 | * unzip zip file to dest folder
82 | * @param zipFilePath
83 | * @param destPath
84 | */
85 | public static void $unzip(String zipFilePath, String destPath) throws IOException {
86 | // check or create dest folder
87 | File destFile = new File(destPath);
88 | if (!destFile.exists()) {
89 | destFile.mkdirs();
90 | }
91 |
92 | // start unzip
93 | ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath));
94 | ZipEntry zipEntry;
95 | String zipEntryName;
96 | while ((zipEntry = zipInputStream.getNextEntry()) != null) {
97 | zipEntryName = zipEntry.getName();
98 | if (zipEntry.isDirectory()) {
99 | File folder = new File(destPath + File.separator + zipEntryName);
100 | folder.mkdirs();
101 | } else {
102 | File file = new File(destPath + File.separator + zipEntryName);
103 | if (file != null && !file.getParentFile().exists()) {
104 | file.getParentFile().mkdirs();
105 | }
106 | file.createNewFile();
107 | FileOutputStream out = new FileOutputStream(file);
108 | int len;
109 | byte[] buffer = new byte[1024];
110 | while ((len = zipInputStream.read(buffer)) > 0) {
111 | out.write(buffer, 0, len);
112 | out.flush();
113 | }
114 | out.close();
115 | }
116 | }
117 | zipInputStream.close();
118 | }
119 |
120 | /**
121 | * 删除文件或者文件夹,默认保留根目录
122 | * @param directory
123 | */
124 | public static void $del(File directory) {
125 | $del(directory, false);
126 | }
127 |
128 | /**
129 | * 删除文件或者文件夹
130 | * @param directory
131 | */
132 | public static void $del(File directory, boolean keepRoot) {
133 | if (directory != null && directory.exists()) {
134 | if (directory.isDirectory()) {
135 | for (File subDirectory : directory.listFiles()) {
136 | $del(subDirectory, false);
137 | }
138 | }
139 |
140 | if (!keepRoot) {
141 | directory.delete();
142 | }
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/HttpLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.ContentValues;
4 |
5 | import java.io.DataOutputStream;
6 | import java.io.File;
7 | import java.io.FileInputStream;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.OutputStream;
12 | import java.net.HttpURLConnection;
13 | import java.net.URL;
14 | import java.util.Map;
15 | import java.util.UUID;
16 | import java.util.concurrent.ExecutorService;
17 | import java.util.concurrent.Executors;
18 | import java.util.zip.GZIPInputStream;
19 |
20 | public final class HttpLess {
21 |
22 | private static ExecutorService mExecutorService = Executors.newFixedThreadPool(4);
23 |
24 | /**
25 | * 同步get方式获取url内容
26 | * @param url
27 | * @return
28 | */
29 | public static String $get(String url) {
30 | return $get(url, new ContentValues());
31 | }
32 |
33 | /**
34 | * 同步get方式获取url内容,支持自定义Header
35 | * @param url
36 | * @param header
37 | * @return
38 | */
39 | public static String $get(String url, ContentValues header) {
40 | InputStream is = null;
41 | try {
42 | URL u = new URL(url);
43 | HttpURLConnection conn = (HttpURLConnection) u.openConnection();
44 | conn.setUseCaches(false);
45 | conn.setConnectTimeout($.sConnectTimeOut);
46 | conn.setReadTimeout($.sReadTimeout);
47 | conn.setRequestMethod("GET");
48 |
49 | // 自定义header
50 | for (Map.Entry entry : header.valueSet()) {
51 | String key = entry.getKey();
52 | String value = entry.getValue().toString();
53 | conn.setRequestProperty(key, value);
54 | }
55 | if (conn.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM
56 | || conn.getResponseCode()== HttpURLConnection.HTTP_MOVED_TEMP) {
57 | // 重定向地址下载
58 | String redirectDownloadUrl = conn.getHeaderField("location");
59 | return $get(redirectDownloadUrl, header);
60 | } else if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
61 | is = conn.getInputStream();
62 | return FileLess.$read(is);
63 | }
64 | } catch (IOException e) {
65 | e.printStackTrace();
66 | } catch (Exception e) {
67 | e.printStackTrace();
68 | } finally {
69 | if (is != null) {
70 | try {
71 | is.close();
72 | } catch (IOException e) {
73 | e.printStackTrace();
74 | }
75 | }
76 | }
77 | return null;
78 | }
79 |
80 | /**
81 | * 异步get方式获取url内容
82 | * @param url
83 | * @param callBack 包含一个onFinish方法的回调,并带上结果result参数
84 | */
85 | public static void $get(final String url, final CallBack callBack) {
86 | $get(url, new ContentValues(), callBack);
87 | }
88 |
89 | public static void $get(final String url, final ContentValues header, final CallBack callBack) {
90 | mExecutorService.submit(new Runnable() {
91 | @Override
92 | public void run() {
93 | String result = $get(url, header);
94 | callBack.onFinish(result);
95 | }
96 | });
97 | }
98 |
99 | /**
100 | * 同步post方式获取url内容
101 | * @param url
102 | * @param params
103 | * @return
104 | */
105 | public static String $post(String url, ContentValues params) {
106 | return $post(url, params, new ContentValues());
107 | }
108 |
109 | /**
110 | * 同步post方式获取url内容,支持自定义Header
111 | * @param url
112 | * @param params
113 | * @return
114 | */
115 | public static String $post(String url, ContentValues params, ContentValues header) {
116 | if (params == null || params.size() == 0) {
117 | return $get(url);
118 | }
119 | OutputStream os = null;
120 | InputStream is = null;
121 | StringBuffer body = new StringBuffer();
122 |
123 | // 拼接参数
124 | for (Map.Entry entry : params.valueSet()) {
125 | String key = entry.getKey();
126 | String value = entry.getValue().toString();
127 | body.append(key).append('=').append(value);
128 | body.append('&');
129 | }
130 | // 去掉最尾部多余的&符号
131 | if (body.length() > 0) {
132 | body = body.deleteCharAt(body.length() - 1);
133 | }
134 |
135 | byte[] data = body.toString().getBytes();
136 | try {
137 | URL u = new URL(url);
138 | HttpURLConnection conn = (HttpURLConnection) u.openConnection();
139 | conn.setConnectTimeout($.sConnectTimeOut);
140 | conn.setReadTimeout($.sReadTimeout);
141 | conn.setRequestMethod("POST");
142 | conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
143 | conn.setRequestProperty("Content-Length", String.valueOf(data.length));
144 |
145 | // 自定义header
146 | for (Map.Entry entry : header.valueSet()) {
147 | String key = entry.getKey();
148 | String value = entry.getValue().toString();
149 | conn.setRequestProperty(key, value);
150 | }
151 | conn.setDoOutput(true);
152 | os = conn.getOutputStream();
153 | os.write(data);
154 | if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
155 | is = conn.getInputStream();
156 | return FileLess.$read(is);
157 | }
158 | } catch (Exception e) {
159 | e.printStackTrace();
160 | } finally {
161 | if (os != null) {
162 | try {
163 | os.close();
164 | } catch (IOException e) {
165 | e.printStackTrace();
166 | }
167 | }
168 | if (is != null) {
169 | try {
170 | is.close();
171 | } catch (IOException e) {
172 | e.printStackTrace();
173 | }
174 | }
175 | }
176 | return null;
177 | }
178 |
179 | /**
180 | * 异步post方式获取url内容
181 | * @param url
182 | * @param params
183 | * @param callBack 包含一个onFinish方法的回调,并带上结果result参数
184 | */
185 | public static void $post(final String url, final ContentValues params, final CallBack callBack) {
186 | $post(url, params, new ContentValues(), callBack);
187 | }
188 |
189 | /**
190 | * 异步post方式获取url内容,支持自定义Header
191 | * @param url
192 | * @param params
193 | * @param header
194 | * @param callBack 包含一个onFinish方法的回调,并带上结果result参数
195 | */
196 | public static void $post(final String url, final ContentValues params, final ContentValues header, final CallBack callBack) {
197 | mExecutorService.submit(new Runnable() {
198 | @Override
199 | public void run() {
200 | String result = $post(url, params, header);
201 | callBack.onFinish(result);
202 | }
203 | });
204 | }
205 |
206 | /**
207 | * 异步下载文件
208 | * @param downloadUrl
209 | * @param dest
210 | * @param append
211 | * @param callBack
212 | * @return
213 | * @throws Exception
214 | */
215 | public static long $download(String downloadUrl, File dest, boolean append, DownloadCallBack callBack) throws Exception {
216 | return $download(downloadUrl, dest, append, new ContentValues(), callBack);
217 | }
218 |
219 | /**
220 | * 异步下载文件,支持自定义Header
221 | * @param downloadUrl
222 | * @param dest
223 | * @param append
224 | * @param header
225 | * @param callBack
226 | * @return
227 | * @throws Exception
228 | */
229 | public static long $download(String downloadUrl, File dest, boolean append, ContentValues header, DownloadCallBack callBack) throws Exception {
230 | int progress = 0;
231 | long remoteSize = 0;
232 | int currentSize = 0;
233 | long totalSize = -1;
234 |
235 | if (!append && dest.exists() && dest.isFile()) {
236 | dest.delete();
237 | }
238 |
239 | if (append && dest.exists()) {
240 | FileInputStream fis = null;
241 | try {
242 | fis = new FileInputStream(dest);
243 | currentSize = fis.available();
244 | } catch (IOException e) {
245 | throw e;
246 | } finally {
247 | if (fis != null) {
248 | fis.close();
249 | }
250 | }
251 | }
252 |
253 | InputStream is = null;
254 | FileOutputStream os = null;
255 | try {
256 | URL u = new URL(downloadUrl);
257 | HttpURLConnection conn = (HttpURLConnection) u.openConnection();
258 | conn.setUseCaches(false);
259 | conn.setConnectTimeout($.sConnectTimeOut);
260 | conn.setReadTimeout($.sReadTimeout);
261 | conn.setRequestMethod("GET");
262 | // 设置断点续传的起始位置
263 | if (currentSize > 0) {
264 | conn.setRequestProperty("RANGE", "bytes=" + currentSize + "-");
265 | }
266 | // 自定义header
267 | for (Map.Entry entry : header.valueSet()) {
268 | String key = entry.getKey();
269 | String value = entry.getValue().toString();
270 | conn.setRequestProperty(key, value);
271 | }
272 | if (conn.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM
273 | || conn.getResponseCode()== HttpURLConnection.HTTP_MOVED_TEMP) {
274 | // 重定向地址下载
275 | String redirectDownloadUrl = conn.getHeaderField("location");
276 | return $download(redirectDownloadUrl, dest, append, header, callBack);
277 | } else if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
278 | is = conn.getInputStream();
279 | remoteSize = conn.getContentLength();
280 | String contentEndcoding = conn.getHeaderField("Content-Encoding");
281 | if (contentEndcoding != null && contentEndcoding.equalsIgnoreCase("gzip")) {
282 | is = new GZIPInputStream(is);
283 | }
284 | os = new FileOutputStream(dest, append);
285 | byte buffer[] = new byte[8192];
286 | int readSize = 0;
287 | while ((readSize = is.read(buffer)) > 0) {
288 | os.write(buffer, 0, readSize);
289 | os.flush();
290 | totalSize += readSize;
291 | // 通知回调下载进度
292 | if (callBack != null) {
293 | progress = (int) (totalSize * 100 / remoteSize);
294 | callBack.onDownloading(progress);
295 | }
296 | }
297 |
298 | if (progress != 100) {
299 | callBack.onDownloading(100);
300 | }
301 |
302 | if (totalSize < 0) {
303 | totalSize = 0;
304 | }
305 | }
306 | } catch (Exception e) {
307 | throw e;
308 | } finally {
309 | if (os != null) {
310 | os.close();
311 | }
312 | if (is != null) {
313 | is.close();
314 | }
315 | }
316 |
317 | if (totalSize < 0) {
318 | throw new Exception("Download file fail: " + downloadUrl);
319 | }
320 |
321 | // 下载完成并通知回调
322 | if (callBack != null) {
323 | callBack.onDownloaded();
324 | }
325 |
326 | return totalSize;
327 | }
328 |
329 | /**
330 | * 同步上传文件
331 | * @param url
332 | * @param params
333 | * @param files
334 | * @return
335 | */
336 | public static String $upload(String url, Map params, Map files) {
337 | String BOUNDARY = UUID.randomUUID().toString();
338 | String PREFIX = "--", LINEND = "\r\n";
339 | String MULTIPART_FROM_DATA = "multipart/form-data";
340 |
341 | HttpURLConnection conn = null;
342 | OutputStream os = null;
343 | InputStream is = null;
344 |
345 | try {
346 | URL uri = new URL(url);
347 | conn = (HttpURLConnection) uri.openConnection();
348 | conn.setReadTimeout($.sReadTimeout);
349 | conn.setDoInput(true);
350 | conn.setDoOutput(true);
351 | conn.setUseCaches(false);
352 | conn.setRequestMethod("POST");
353 | conn.setRequestProperty("connection", "keep-alive");
354 | conn.setRequestProperty("Charsert", "UTF-8");
355 | conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);
356 |
357 | // text parameters
358 | StringBuilder sb = new StringBuilder();
359 | for (Map.Entry entry : params.entrySet()) {
360 | sb.append(PREFIX);
361 | sb.append(BOUNDARY);
362 | sb.append(LINEND);
363 | sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
364 | sb.append("Content-Type: text/plain; charset=GBK" + LINEND);
365 | sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
366 | sb.append(LINEND);
367 | sb.append(entry.getValue());
368 | sb.append(LINEND);
369 | }
370 |
371 | os = new DataOutputStream(conn.getOutputStream());
372 | os.write(sb.toString().getBytes());
373 | // send file data
374 | if (files != null)
375 | for (Map.Entry file : files.entrySet()) {
376 | StringBuilder sb1 = new StringBuilder();
377 | sb1.append(PREFIX);
378 | sb1.append(BOUNDARY);
379 | sb1.append(LINEND);
380 | sb1.append("Content-Disposition: form-data; name=\"uploadfile\"; filename=\""
381 | + file.getValue().getName() + "\"" + LINEND);
382 | sb1.append("Content-Type: application/octet-stream; charset=GBK" + LINEND);
383 | sb1.append(LINEND);
384 | os.write(sb1.toString().getBytes());
385 |
386 | is = new FileInputStream(file.getValue());
387 | byte[] buffer = new byte[1024];
388 | int len = 0;
389 | while ((len = is.read(buffer)) != -1) {
390 | os.write(buffer, 0, len);
391 | }
392 | is.close();
393 | os.write(LINEND.getBytes());
394 | }
395 |
396 | byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
397 | os.write(end_data);
398 | os.flush();
399 | if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
400 | InputStream in = conn.getInputStream();
401 | return FileLess.$read(in);
402 | }
403 |
404 | } catch (IOException e) {
405 | e.printStackTrace();
406 | } finally {
407 | if (conn != null) {
408 | conn.disconnect();
409 | }
410 |
411 | if (os != null) {
412 | try {
413 | os.close();
414 | } catch (IOException e) {
415 | e.printStackTrace();
416 | }
417 | }
418 | if (is != null) {
419 | try {
420 | is.close();
421 | } catch (IOException e) {
422 | e.printStackTrace();
423 | }
424 | }
425 | }
426 | return null;
427 | }
428 |
429 | /**
430 | * 异步上传文件
431 | * @param url
432 | * @param params
433 | * @param files
434 | * @param callBack
435 | */
436 | public static void $upload(final String url, final Map params, final Map files, final CallBack callBack) {
437 | mExecutorService.submit(new Runnable() {
438 | @Override
439 | public void run() {
440 | String result = $upload(url, params, files);
441 | callBack.onFinish(result);
442 | }
443 | });
444 | }
445 |
446 | /**
447 | * Http请求回调
448 | * onFinish,带结果字符串
449 | */
450 | public interface CallBack {
451 | void onFinish(String result);
452 | }
453 |
454 | /**
455 | * 下载回调:下载进度和下载完成
456 | * onDownloading,带一个进度值:0~100
457 | * onDownloaded
458 | */
459 | public interface DownloadCallBack {
460 | void onDownloading(int progress);
461 | void onDownloaded();
462 | }
463 | }
464 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/ImageLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.media.ExifInterface;
4 |
5 | import java.io.IOException;
6 |
7 | public final class ImageLess {
8 |
9 | /**
10 | * 获取图片的exif的旋转角度
11 | * @param path
12 | * @return
13 | */
14 | public static int $exifRotateAngle(String path) {
15 | int angle = 0;
16 | try {
17 | ExifInterface exifInterface = new ExifInterface(path);
18 | int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
19 | switch (orientation) {
20 | case ExifInterface.ORIENTATION_ROTATE_90:
21 | angle = 90;
22 | break;
23 | case ExifInterface.ORIENTATION_ROTATE_180:
24 | angle = 180;
25 | break;
26 | case ExifInterface.ORIENTATION_ROTATE_270:
27 | angle = 270;
28 | break;
29 | }
30 | } catch (IOException e) {
31 | e.printStackTrace();
32 | }
33 | return angle;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/KeyBoardLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.inputmethod.InputMethodManager;
6 |
7 | /**
8 | * 输入法相关的工具类
9 | */
10 | public final class KeyBoardLess {
11 |
12 | /**
13 | * 显示输入法
14 | * @param context
15 | * @param view
16 | */
17 | public static void $show(Context context, View view) {
18 | InputMethodManager imm =
19 | (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
20 | imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
21 | imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
22 | }
23 |
24 | /**
25 | * 隐藏输入法
26 | * @param context
27 | * @param view
28 | */
29 | public static void $hide(Context context, View view) {
30 | InputMethodManager imm =
31 | (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
32 | imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/LogLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.text.TextUtils;
4 | import android.util.Log;
5 |
6 | import org.json.JSONArray;
7 | import org.json.JSONException;
8 | import org.json.JSONObject;
9 |
10 | /**
11 | * support for custom log printing out in case
12 | * adb shell setprop log.tag.YOUR_LOG_TAG LEVEL
13 | * for thinking of perfomence, it need restart your app
14 | *
15 | * Example (from system):
16 | * adb shell setprop log.tag.SQLiteLog V
17 | */
18 | public final class LogLess {
19 |
20 | public static final boolean DEBUG_TAG_LOG = Log.isLoggable($.sTAG, Log.VERBOSE);
21 |
22 | private static final int JSON_INDENT = 4;
23 |
24 | /**
25 | * verbose
26 | *
27 | * @param str
28 | */
29 | public static void v(String str, Object... args) {
30 | if ($.sDebug || DEBUG_TAG_LOG) {
31 | Log.v(getTag(), buildLogString(str, args));
32 | }
33 | }
34 |
35 | /**
36 | * debug
37 | *
38 | * @param str
39 | */
40 | public static void $d(String str, Object... args) {
41 | if ($.sDebug || DEBUG_TAG_LOG) {
42 | Log.d(getTag(), buildLogString(str, args));
43 | }
44 | }
45 |
46 | /**
47 | * info
48 | *
49 | * @param str
50 | */
51 | public static void $i(String str, Object... args) {
52 | if ($.sDebug || DEBUG_TAG_LOG) {
53 | Log.i(getTag(), buildLogString(str, args));
54 | }
55 | }
56 |
57 | /**
58 | * warning
59 | *
60 | * @param str
61 | */
62 | public static void $w(String str, Object... args) {
63 | if ($.sDebug || DEBUG_TAG_LOG) {
64 | Log.w(getTag(), buildLogString(str, args));
65 | }
66 | }
67 |
68 | /**
69 | * error
70 | *
71 | * @param str
72 | */
73 | public static void $e(String str, Object... args) {
74 | if ($.sDebug || DEBUG_TAG_LOG) {
75 | Log.e(getTag(), buildLogString(str, args));
76 | }
77 | }
78 |
79 | /**
80 | * json with a title
81 | *
82 | * @param str
83 | * @param title
84 | */
85 | public static void $json(String str, String title) {
86 | if ($.sDebug || DEBUG_TAG_LOG) {
87 | Log.d(getTag(), "|===================================================================");
88 |
89 | if (!TextUtils.isEmpty(title)) {
90 | Log.d(getTag(), "| " + title);
91 | Log.d(getTag(), "|-------------------------------------------------------------------");
92 | }
93 |
94 | String message;
95 | try {
96 | if (str.startsWith("{")) {
97 | JSONObject jsonObject = new JSONObject(str);
98 | message = jsonObject.toString(JSON_INDENT);
99 | } else if (str.startsWith("[")) {
100 | JSONArray jsonArray = new JSONArray(str);
101 | message = jsonArray.toString(JSON_INDENT);
102 | } else {
103 | message = str;
104 | }
105 | } catch (JSONException e) {
106 | message = str;
107 | }
108 |
109 | String[] lines = message.split("\n");
110 | for (String line : lines) {
111 | Log.d(getTag(), line);
112 | }
113 | Log.d(getTag(), "===================================================================|");
114 | }
115 | }
116 |
117 | /**
118 | * json
119 | *
120 | * @param str
121 | */
122 | public static void $json(String str) {
123 | $json(str, null);
124 | }
125 |
126 | /**
127 | * 如果$.sTAG是空则自动从StackTrace中取TAG
128 | *
129 | * @return
130 | */
131 | private static String getTag() {
132 | if (!TextUtils.isEmpty($.sTAG)) {
133 | return $.sTAG;
134 | }
135 | StackTraceElement caller = new Throwable().fillInStackTrace().getStackTrace()[2];
136 | return caller.getFileName();
137 | }
138 |
139 | /**
140 | * 根据StackTrace生成带更多信息的log
141 | * 文件名,方法名,行数
142 | *
143 | * @param str
144 | * @return
145 | */
146 | private static String buildLogString(String str, Object... args) {
147 |
148 | // format string with args
149 | if (args.length > 0) {
150 | str = String.format(str, args);
151 | }
152 |
153 | StackTraceElement caller = new Throwable().fillInStackTrace().getStackTrace()[2];
154 | StringBuilder stringBuilder = new StringBuilder();
155 | if (TextUtils.isEmpty($.sTAG)) {
156 | stringBuilder.append(caller.getMethodName())
157 | .append("():")
158 | .append(caller.getLineNumber())
159 | .append(":")
160 | .append(str);
161 | } else {
162 | stringBuilder
163 | .append("(")
164 | .append(caller.getFileName())
165 | .append(":")
166 | .append(caller.getLineNumber())
167 | .append(").")
168 | .append(caller.getMethodName())
169 | .append("():")
170 | .append(str);
171 | }
172 | return stringBuilder.toString();
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/NetworkLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 | import android.telephony.TelephonyManager;
7 |
8 | /**
9 | * 手机网络相关的工具类
10 | */
11 | public final class NetworkLess {
12 |
13 | /**
14 | * 定义网络类型的枚举分类
15 | * 这里把一些一些2G,2.5G,2.7G等等按照快慢又做了一个分类,仅供参考
16 | */
17 | public static enum NetworkType {
18 | WIRED_FAST, WIFI_FAST, MOBILE_FAST, MOBILE_MIDDLE, MOBILE_SLOW, NONE,
19 | }
20 |
21 | /**
22 | * 是否网络在线
23 | * @return
24 | */
25 | public static boolean $online() {
26 | ConnectivityManager manager = (ConnectivityManager) $.sAppContext
27 | .getSystemService(Context.CONNECTIVITY_SERVICE);
28 | NetworkInfo networkInfo = manager.getActiveNetworkInfo();
29 | if (networkInfo != null) {
30 | return networkInfo.isAvailable();
31 | }
32 | return false;
33 | }
34 |
35 | /**
36 | * 当期的网络类型
37 | * @return
38 | */
39 | public static NetworkType $type() {
40 | ConnectivityManager manager = (ConnectivityManager) $.sAppContext
41 | .getSystemService(Context.CONNECTIVITY_SERVICE);
42 | NetworkInfo info = manager.getActiveNetworkInfo();
43 |
44 | if (info == null || !info.isConnected()) {
45 | return NetworkType.NONE;
46 | }
47 |
48 | int type = info.getType();
49 | int subType = info.getSubtype();
50 |
51 |
52 | if (type == ConnectivityManager.TYPE_ETHERNET) {
53 | return NetworkType.WIRED_FAST;
54 | }
55 |
56 | if (type == ConnectivityManager.TYPE_WIFI) {
57 | return NetworkType.WIFI_FAST;
58 | }
59 |
60 | if (type == ConnectivityManager.TYPE_MOBILE) {
61 | switch (subType) {
62 | case TelephonyManager.NETWORK_TYPE_GPRS:
63 | case TelephonyManager.NETWORK_TYPE_GSM:
64 | case TelephonyManager.NETWORK_TYPE_EDGE:
65 | case TelephonyManager.NETWORK_TYPE_CDMA:
66 | case TelephonyManager.NETWORK_TYPE_1xRTT:
67 | case TelephonyManager.NETWORK_TYPE_IDEN:
68 | return NetworkType.MOBILE_SLOW; // 2G
69 |
70 | case TelephonyManager.NETWORK_TYPE_UMTS:
71 | case TelephonyManager.NETWORK_TYPE_EVDO_0:
72 | case TelephonyManager.NETWORK_TYPE_EVDO_A:
73 | case TelephonyManager.NETWORK_TYPE_HSDPA:
74 | case TelephonyManager.NETWORK_TYPE_HSUPA:
75 | case TelephonyManager.NETWORK_TYPE_HSPA:
76 | case TelephonyManager.NETWORK_TYPE_EVDO_B:
77 | case TelephonyManager.NETWORK_TYPE_EHRPD:
78 | case TelephonyManager.NETWORK_TYPE_HSPAP:
79 | case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
80 | return NetworkType.MOBILE_MIDDLE;// 3G
81 |
82 | case TelephonyManager.NETWORK_TYPE_LTE:
83 | case TelephonyManager.NETWORK_TYPE_IWLAN:
84 | case 19: // TelephonyManager.NETWORK_TYPE_LTE_CA
85 | return NetworkType.MOBILE_FAST; // 4G
86 | default: // we think the network will be more and more better
87 | return NetworkType.MOBILE_FAST;
88 | }
89 | }
90 |
91 | return NetworkType.NONE;
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/ResourceLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 |
6 | public final class ResourceLess {
7 |
8 | /**
9 | * 根据资源名称和类型,得到资源ID
10 | * @param context
11 | * @param resourceName
12 | * @param type
13 | * @return
14 | */
15 | public static int $id(Context context, String resourceName, TYPE type) {
16 | Resources resources = context.getResources();
17 | return resources.getIdentifier(resourceName, type.getString(), context.getPackageName());
18 | }
19 |
20 | /**
21 | * 定义资源枚举类型
22 | */
23 | public enum TYPE {
24 | ATTR("attr"),
25 | ARRAY("array"),
26 | ANIM("anim"),
27 | BOOL("bool"),
28 | COLOR("color"),
29 | DIMEN("dimen"),
30 | DRAWABLE("drawable"),
31 | ID("id"),
32 | INTEGER("integer"),
33 | LAYOUT("layout"),
34 | MENU("menu"),
35 | MIPMAP("mipmap"),
36 | RAW("raw"),
37 | STRING("string"),
38 | STYLE("style"),
39 | STYLEABLE("styleable");
40 |
41 | private String string;
42 | TYPE(String string) {
43 | this.string = string;
44 | }
45 | public String getString() {
46 | return string;
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/SerializeLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.ObjectInputStream;
7 | import java.io.ObjectOutputStream;
8 |
9 | /**
10 | * 序列化相关的工具类
11 | */
12 | public final class SerializeLess {
13 |
14 | /**
15 | * 序列化对象到本地文件
16 | * @param path
17 | * @param object
18 | * @param
19 | */
20 | public static void $se(String path, T object) {
21 | ObjectOutputStream out = null;
22 | try {
23 | out = new ObjectOutputStream(new FileOutputStream(path));
24 | out.writeObject(object);
25 | out.close();
26 | } catch (Exception e) {
27 | e.printStackTrace();
28 | } finally {
29 | if (out != null) {
30 | try {
31 | out.close();
32 | } catch (IOException e) {
33 | e.printStackTrace();
34 | }
35 | }
36 | }
37 | }
38 |
39 | /**
40 | * 从本地文件中解析出序列化对象
41 | * @param path
42 | * @param
43 | * @return
44 | */
45 | public static T $de(String path) {
46 | ObjectInputStream in = null;
47 | try {
48 | in = new ObjectInputStream(new FileInputStream(path));
49 | Object o = in.readObject();
50 | in.close();
51 | return (T)o;
52 | } catch (Exception e) {
53 | e.printStackTrace();
54 | } finally {
55 | if (in != null) {
56 | try {
57 | in.close();
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | }
61 | }
62 | }
63 | return null;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/SharedPreferenceLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | import java.lang.reflect.InvocationTargetException;
7 | import java.lang.reflect.Method;
8 |
9 | public final class SharedPreferenceLess {
10 |
11 | public static final String SHARED_NAME = "shared_name";
12 |
13 | public static void $put(String key, T value) {
14 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
15 | Context.MODE_PRIVATE);
16 | SharedPreferences.Editor editor = sp.edit();
17 |
18 | if (value == null) {
19 | // if value is null, just handler it as a String
20 | editor.putString(key, null);
21 | } else {
22 | if (value.getClass() == Boolean.class) {
23 | editor.putBoolean(key, (Boolean) value);
24 | } else if (value.getClass() == Float.class) {
25 | editor.putFloat(key, (Float) value);
26 | } else if (value.getClass() == Integer.class) {
27 | editor.putInt(key, (Integer) value);
28 | } else if (value.getClass() == Long.class) {
29 | editor.putLong(key, (Long) value);
30 | } else if (value.getClass() == String.class) {
31 | editor.putString(key, (String) value);
32 | } else {
33 | throw new RuntimeException("the put value type can't support.");
34 | }
35 | }
36 |
37 | SharedPreferencesCompat.apply(editor);
38 | }
39 |
40 | public static String $get(String key, String defaultValue) {
41 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
42 | Context.MODE_PRIVATE);
43 | return sp.getString(key, defaultValue);
44 | }
45 |
46 | public static boolean $get(String key, boolean defaultValue) {
47 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
48 | Context.MODE_PRIVATE);
49 | return sp.getBoolean(key, defaultValue);
50 | }
51 |
52 | public static float $get(String key, float defaultValue) {
53 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
54 | Context.MODE_PRIVATE);
55 | return sp.getFloat(key, defaultValue);
56 | }
57 |
58 | public static int $get(String key, int defaultValue) {
59 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
60 | Context.MODE_PRIVATE);
61 | return sp.getInt(key, defaultValue);
62 | }
63 |
64 | public static long $get(String key, long defaultValue) {
65 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
66 | Context.MODE_PRIVATE);
67 | return sp.getLong(key, defaultValue);
68 | }
69 |
70 | public static void $remove(String key) {
71 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
72 | Context.MODE_PRIVATE);
73 | SharedPreferences.Editor editor = sp.edit();
74 | editor.remove(key);
75 | SharedPreferencesCompat.apply(editor);
76 | }
77 |
78 | public static void $clear() {
79 | SharedPreferences sp = $.sAppContext.getSharedPreferences(SHARED_NAME,
80 | Context.MODE_PRIVATE);
81 | SharedPreferences.Editor editor = sp.edit();
82 | editor.clear();
83 | SharedPreferencesCompat.apply(editor);
84 | }
85 |
86 |
87 | /**
88 | * *********************************************************************************************
89 | * Unlike commit(), which writes its preferences out to persistent storage synchronously,
90 | * apply() commits its changes to the in-memory SharedPreferencesimmediately
91 | * but starts an asynchronous commit to disk and you won't be notified of any failures.
92 | * If another editor on this SharedPreferences does a regularcommit() while a apply() is still outstanding,
93 | * the commit() will block until all async commits are completed as well as the commit itself.
94 | * *********************************************************************************************
95 | */
96 | private static class SharedPreferencesCompat {
97 | private static final Method sApplyMethod = findApplyMethod();
98 |
99 | /**
100 | * check apply mthod by reflect
101 | *
102 | * @return
103 | */
104 | @SuppressWarnings({"unchecked", "rawtypes"})
105 | private static Method findApplyMethod() {
106 | try {
107 | Class clz = SharedPreferences.Editor.class;
108 | return clz.getMethod("apply");
109 | } catch (NoSuchMethodException e) {
110 | }
111 |
112 | return null;
113 | }
114 |
115 | /**
116 | * if it has apply(), use apply() first;
117 | * else just use the commit().
118 | *
119 | * @param editor
120 | */
121 | public static void apply(SharedPreferences.Editor editor) {
122 | try {
123 | if (sApplyMethod != null) {
124 | sApplyMethod.invoke(editor);
125 | return;
126 | }
127 | } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
128 | e.printStackTrace();
129 | }
130 | editor.commit();
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/StorageLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.os.Environment;
5 | import android.os.StatFs;
6 | import android.text.format.Formatter;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.File;
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.io.InputStreamReader;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * 手机存储相关的工具类
18 | * 包括:手机内存,内置存储卡(Sdcard),外置存储卡(ExtSdcard)
19 | */
20 | public final class StorageLess {
21 |
22 | /**
23 | * 手机内存
24 | */
25 | public static class Phone {
26 | public static long $total() {
27 | File path = Environment.getDataDirectory();
28 | return total(path);
29 | }
30 |
31 | public static long $used() {
32 | File path = Environment.getDataDirectory();
33 | return used(path);
34 | }
35 |
36 | public static long $free() {
37 | File path = Environment.getDataDirectory();
38 | return free(path);
39 | }
40 |
41 | public static String $totalString(Context context) {
42 | return Formatter.formatFileSize(context, $total());
43 | }
44 | public static String $usedString(Context context) {
45 | return Formatter.formatFileSize(context, $used());
46 | }
47 | public static String $freeString(Context context) {
48 | return Formatter.formatFileSize(context, $free());
49 | }
50 |
51 | }
52 |
53 | /**
54 | * 内部存储
55 | * 1. 如果没有内部存储,则为外部存储
56 | * 2. 一般默认说的sdcard就是指这一层
57 | */
58 | public static class Sdcard {
59 |
60 | public static boolean $ready() {
61 | String state = Environment.getExternalStorageState();
62 | return Environment.MEDIA_MOUNTED.equals(state);
63 | }
64 |
65 | public static File $path() {
66 | return Environment.getExternalStorageDirectory();
67 | }
68 |
69 | public static long $total() {
70 | File path = Environment.getExternalStorageDirectory();
71 | return total(path);
72 | }
73 |
74 | public static long $used() {
75 | File path = Environment.getExternalStorageDirectory();
76 | return used(path);
77 | }
78 |
79 | public static long $free() {
80 | File path = Environment.getExternalStorageDirectory();
81 | return free(path);
82 | }
83 |
84 | public static String $totalString(Context context) {
85 | return Formatter.formatFileSize(context, $total());
86 | }
87 | public static String $usedString(Context context) {
88 | return Formatter.formatFileSize(context, $used());
89 | }
90 | public static String $freeString(Context context) {
91 | return Formatter.formatFileSize(context, $free());
92 | }
93 | }
94 |
95 | /**
96 | * 外部存储
97 | */
98 | public static class ExtSdcard {
99 |
100 | public static File $path() {
101 | List paths = new ArrayList();
102 | String extFileStatus = Environment.getExternalStorageState();
103 | File extFile = Environment.getExternalStorageDirectory();
104 | if (extFileStatus.equals(Environment.MEDIA_MOUNTED)
105 | && extFile.exists() && extFile.isDirectory()
106 | && extFile.canWrite()) {
107 | paths.add(extFile.getAbsolutePath());
108 | }
109 | try {
110 | // obtain executed result of command line code of 'mount', to judge
111 | // whether tfCard exists by the result
112 | Runtime runtime = Runtime.getRuntime();
113 | Process process = runtime.exec("mount");
114 | InputStream is = process.getInputStream();
115 | InputStreamReader isr = new InputStreamReader(is);
116 | BufferedReader br = new BufferedReader(isr);
117 | String line = null;
118 | int mountPathIndex = 1;
119 | while ((line = br.readLine()) != null) {
120 | // format of sdcard file system: vfat/fuse
121 | if ((!line.contains("fat") && !line.contains("fuse") && !line
122 | .contains("storage"))
123 | || line.contains("secure")
124 | || line.contains("asec")
125 | || line.contains("firmware")
126 | || line.contains("shell")
127 | || line.contains("obb")
128 | || line.contains("legacy") || line.contains("data")) {
129 | continue;
130 | }
131 | String[] parts = line.split(" ");
132 | int length = parts.length;
133 | if (mountPathIndex >= length) {
134 | continue;
135 | }
136 | String mountPath = parts[mountPathIndex];
137 | if (!mountPath.contains("/") || mountPath.contains("data")
138 | || mountPath.contains("Data")) {
139 | continue;
140 | }
141 | File mountRoot = new File(mountPath);
142 | if (!mountRoot.exists() || !mountRoot.isDirectory()
143 | || !mountRoot.canWrite()) {
144 | continue;
145 | }
146 | boolean equalsToPrimarySD = mountPath.equals(extFile
147 | .getAbsolutePath());
148 | if (equalsToPrimarySD) {
149 | continue;
150 | }
151 | paths.add(mountPath);
152 | }
153 | } catch (IOException e) {
154 | e.printStackTrace();
155 | }
156 | if (paths.size() > 1) {
157 | return new File(paths.get(1));
158 | }
159 | return null;
160 | }
161 |
162 | public static long $total() {
163 | File path = Environment.getExternalStorageDirectory();
164 | return total(path);
165 | }
166 |
167 | public static long $used() {
168 | File path = Environment.getExternalStorageDirectory();
169 | return used(path);
170 | }
171 |
172 | public static long $free() {
173 | File path = Environment.getExternalStorageDirectory();
174 | return free(path);
175 | }
176 |
177 | public static String $totalString(Context context) {
178 | return Formatter.formatFileSize(context, $total());
179 | }
180 | public static String $usedString(Context context) {
181 | return Formatter.formatFileSize(context, $used());
182 | }
183 | public static String $freeString(Context context) {
184 | return Formatter.formatFileSize(context, $free());
185 | }
186 | }
187 |
188 | private static long total(File path) {
189 | try {
190 | StatFs stat = new StatFs(path.getPath());
191 | long blockSize = stat.getBlockSize();
192 | long totalBlocks = stat.getBlockCount();
193 | return blockSize * totalBlocks;
194 | } catch (Exception e) {
195 | e.printStackTrace();
196 | }
197 |
198 | return 0;
199 | }
200 |
201 | private static long free(File path) {
202 | try {
203 | StatFs stat = new StatFs(path.getPath());
204 | long blockSize = stat.getBlockSize();
205 | long freeBlocks = stat.getAvailableBlocks();
206 | return blockSize * freeBlocks;
207 | } catch (Exception e) {
208 | e.printStackTrace();
209 | }
210 |
211 | return 0;
212 | }
213 |
214 | private static long used(File path) {
215 | return total(path) - free(path);
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/ToastLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.content.Context;
4 | import android.widget.Toast;
5 |
6 | /**
7 | * 简化Toast的工具类
8 | */
9 | public final class ToastLess {
10 |
11 | @Deprecated
12 | public static void $(Context context, String message) {
13 | Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_SHORT).show();
14 | }
15 |
16 | @Deprecated
17 | public static void $(Context context, int stringId) {
18 | Toast.makeText(context.getApplicationContext(), stringId, Toast.LENGTH_SHORT).show();
19 | }
20 |
21 | public static void $(String message) {
22 | Toast.makeText($.sAppContext, message, Toast.LENGTH_SHORT).show();
23 | }
24 |
25 | public static void $(int stringId) {
26 | Toast.makeText($.sAppContext, stringId, Toast.LENGTH_SHORT).show();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/ViewLess.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.view.View;
6 |
7 | import java.util.Calendar;
8 |
9 | /**
10 | * View相关工具类
11 | */
12 | public final class ViewLess {
13 |
14 | /**
15 | * ***********************************************************
16 | * findViewById的一种更优雅的写法
17 | * 原理:泛型的类型推断
18 | * ***********************************************************
19 | */
20 | public static T $(Activity activity, int viewId) {
21 | return (T) activity.findViewById(viewId);
22 | }
23 |
24 | public static T $(View view, int viewId) {
25 | return (T) view.findViewById(viewId);
26 | }
27 |
28 | public static T $(Dialog dialog, int viewId) {
29 | return (T) dialog.findViewById(viewId);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/other/DividerItemDecoration.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core.other;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Rect;
7 | import android.graphics.drawable.Drawable;
8 | import android.support.v4.view.ViewCompat;
9 | import android.support.v7.widget.GridLayoutManager;
10 | import android.support.v7.widget.LinearLayoutManager;
11 | import android.support.v7.widget.RecyclerView;
12 | import android.view.View;
13 |
14 | /**
15 | * RecyclerView的ItemDecoration的默认实现
16 | * 1. 默认使用系统的分割线
17 | * 2. 支持自定义Drawable类型
18 | * 3. 支持水平和垂直方向
19 | * 4. 修复了官方垂直Divider显示的bug
20 | * 5. 增加支持GRID_LIST的分割线, 但仅支持空视图分割(如果嫌弃左右上下多余的padding, 可以在RecyclerView中设置padding为负值解决)
21 | * 扩展自官方android sdk下的Support7Demos下的DividerItemDecoration
22 | */
23 | public class DividerItemDecoration extends RecyclerView.ItemDecoration {
24 |
25 | private static final int[] ATTRS = new int[]{
26 | android.R.attr.listDivider
27 | };
28 |
29 | public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
30 | public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
31 | public static final int GRID_LIST = LinearLayoutManager.VERTICAL + 1;
32 |
33 | private Drawable mDivider;
34 | private int mWidth;
35 | private int mHeight;
36 |
37 | private int mOrientation;
38 |
39 | public DividerItemDecoration(Context context, int orientation) {
40 | final TypedArray a = context.obtainStyledAttributes(ATTRS);
41 | mDivider = a.getDrawable(0);
42 | a.recycle();
43 | setOrientation(orientation);
44 | }
45 |
46 | /**
47 | * 新增:支持自定义dividerDrawable
48 | *
49 | * @param context
50 | * @param orientation
51 | * @param dividerDrawable
52 | */
53 | public DividerItemDecoration(Context context, int orientation, Drawable dividerDrawable) {
54 | mDivider = dividerDrawable;
55 | setOrientation(orientation);
56 | }
57 |
58 | public void setOrientation(int orientation) {
59 | if (orientation != HORIZONTAL_LIST
60 | && orientation != VERTICAL_LIST
61 | && orientation != GRID_LIST) {
62 | throw new IllegalArgumentException("invalid orientation");
63 | }
64 | mOrientation = orientation;
65 | }
66 |
67 | /**
68 | * 新增:支持手动为无高宽的drawable制定宽度
69 | *
70 | * @param width
71 | */
72 | public void setWidth(int width) {
73 | this.mWidth = width;
74 | }
75 |
76 | /**
77 | * 新增:支持手动为无高宽的drawable制定高度
78 | *
79 | * @param height
80 | */
81 | public void setHeight(int height) {
82 | this.mHeight = height;
83 | }
84 |
85 | @Override
86 | public void onDraw(Canvas c, RecyclerView parent) {
87 | if (mOrientation == VERTICAL_LIST) {
88 | drawVertical(c, parent);
89 | } else if (mOrientation == HORIZONTAL_LIST) {
90 | drawHorizontal(c, parent);
91 | }
92 | }
93 |
94 | public void drawVertical(Canvas c, RecyclerView parent) {
95 | int left = parent.getPaddingLeft();
96 | int right = parent.getWidth() - parent.getPaddingRight();
97 |
98 | final int childCount = parent.getChildCount();
99 | for (int i = 0; i < childCount; i++) {
100 | final View child = parent.getChildAt(i);
101 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
102 | .getLayoutParams();
103 | int top = child.getBottom() + params.bottomMargin +
104 | Math.round(ViewCompat.getTranslationY(child));
105 | int bottom = top + getDividerHeight();
106 |
107 |
108 | mDivider.setBounds(left, top, right, bottom);
109 | mDivider.draw(c);
110 | }
111 | }
112 |
113 | public void drawHorizontal(Canvas c, RecyclerView parent) {
114 | int top = parent.getPaddingTop();
115 | int bottom = parent.getHeight() - parent.getPaddingBottom();
116 |
117 | final int childCount = parent.getChildCount();
118 | for (int i = 0; i < childCount; i++) {
119 | final View child = parent.getChildAt(i);
120 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
121 | .getLayoutParams();
122 | int left = child.getRight() + params.rightMargin +
123 | Math.round(ViewCompat.getTranslationX(child));
124 | int right = left + getDividerWidth();
125 |
126 | mDivider.setBounds(left, top, right, bottom);
127 | mDivider.draw(c);
128 | }
129 | }
130 |
131 | @Override
132 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
133 | if (mOrientation == VERTICAL_LIST) {
134 | outRect.set(0, 0, 0, getDividerHeight());
135 | } else if (mOrientation == HORIZONTAL_LIST) {
136 | outRect.set(0, 0, getDividerWidth(), 0);
137 | } else if (mOrientation == GRID_LIST) {
138 | outRect.set(getDividerWidth(), getDividerHeight(), getDividerWidth(), getDividerHeight());
139 | }
140 | }
141 |
142 | private int getDividerWidth() {
143 | return mWidth > 0 ? mWidth : mDivider.getIntrinsicWidth();
144 | }
145 |
146 | private int getDividerHeight() {
147 | return mHeight > 0 ? mHeight : mDivider.getIntrinsicHeight();
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/other/SpaceDividerView.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core.other;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.util.AttributeSet;
9 | import android.util.TypedValue;
10 | import android.view.View;
11 |
12 | import com.jayfeng.lesscode.core.R;
13 |
14 | public class SpaceDividerView extends View {
15 |
16 | private int mSpaceLeft = 0;
17 | private int mSpaceTop = 0;
18 | private int mSpaceRight = 0;
19 | private int mSpaceBottom = 0;
20 | private int mSpaceColor = Color.TRANSPARENT;
21 |
22 | private Paint mPaint = new Paint();
23 |
24 | public SpaceDividerView(Context context) {
25 | this(context, null);
26 | }
27 |
28 | public SpaceDividerView(Context context, AttributeSet attrs) {
29 | this(context, attrs, 0);
30 | }
31 |
32 | public SpaceDividerView(Context context, AttributeSet attrs, int defStyleAttr) {
33 | super(context, attrs, defStyleAttr);
34 |
35 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpaceDividerView, defStyleAttr, 0);
36 | mSpaceLeft = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceLeft,
37 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
38 | mSpaceTop = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceTop,
39 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
40 | mSpaceRight = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceRight,
41 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
42 | mSpaceBottom = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceBottom,
43 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
44 | mSpaceColor = a.getColor(R.styleable.SpaceDividerView_spaceColor, Color.TRANSPARENT);
45 | a.recycle();
46 |
47 | mPaint.setColor(mSpaceColor);
48 | }
49 |
50 | @Override
51 | protected void onDraw(Canvas canvas) {
52 | super.onDraw(canvas);
53 | if (mSpaceLeft > 0) {
54 | canvas.drawRect(0, 0, mSpaceLeft, getMeasuredHeight(), mPaint);
55 | }
56 | if (mSpaceTop > 0) {
57 | canvas.drawRect(0, 0, getMeasuredWidth(), mSpaceTop, mPaint);
58 | }
59 | if (mSpaceRight > 0) {
60 | canvas.drawRect(getMeasuredWidth() - mSpaceRight, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
61 | }
62 | if (mSpaceBottom > 0) {
63 | canvas.drawRect(0, getMeasuredHeight() - mSpaceBottom, getMeasuredWidth(), getMeasuredHeight(), mPaint);
64 | }
65 | }
66 |
67 | public void setSpaceLeft(int spaceLeft) {
68 | this.mSpaceLeft = spaceLeft;
69 | invalidate();
70 | }
71 |
72 | public void setSpaceTop(int spaceTop) {
73 | this.mSpaceTop = spaceTop;
74 | invalidate();
75 | }
76 |
77 | public void setSpaceRight(int spaceRight) {
78 | this.mSpaceRight = spaceRight;
79 | invalidate();
80 | }
81 |
82 | public void setSpaceBottom(int spaceBottom) {
83 | this.mSpaceBottom = spaceBottom;
84 | invalidate();
85 | }
86 |
87 | public void setSpaceColor(int spaceColor) {
88 | this.mSpaceColor = spaceColor;
89 | invalidate();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/other/ViewThrottleClickListener.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core.other;
2 |
3 | import android.view.View;
4 |
5 | import java.util.Calendar;
6 |
7 | /**
8 | * 防止快速点击的ClickListener
9 | */
10 | public abstract class ViewThrottleClickListener implements View.OnClickListener {
11 | private static final int THROTTLE_TIME_DEFAULT = 1000; // 1s
12 | private long mLastClickTime = 0;
13 |
14 | public long getThrottleTime() {
15 | return THROTTLE_TIME_DEFAULT;
16 | }
17 | public void discardClick() {}
18 |
19 | public abstract void throttleClick(View view);
20 |
21 | @Override
22 | public void onClick(View v) {
23 | long currentTime = Calendar.getInstance().getTimeInMillis();
24 | if (currentTime - mLastClickTime > getThrottleTime()) {
25 | mLastClickTime = currentTime;
26 | throttleClick(v);
27 | } else {
28 | discardClick();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/java/com/jayfeng/lesscode/core/other/WeakHandler.java:
--------------------------------------------------------------------------------
1 | package com.jayfeng.lesscode.core.other;
2 |
3 | import android.os.Handler;
4 |
5 | import java.lang.ref.WeakReference;
6 |
7 | public abstract class WeakHandler extends Handler {
8 | private WeakReference mOwner;
9 |
10 | public WeakHandler(T owner) {
11 | mOwner = new WeakReference<>(owner);
12 | }
13 |
14 | public T getOwner() {
15 | return mOwner.get();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values-hdpi/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | false
6 | true
7 | false
8 | false
9 | false
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values-ldpi/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | false
5 | false
6 | false
7 | false
8 | false
9 | false
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values-mdpi/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | true
5 | false
6 | false
7 | false
8 | false
9 | false
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values-tvdpi/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | true
6 | false
7 | false
8 | false
9 | false
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values-xhdpi/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | false
6 | false
7 | true
8 | false
9 | false
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values-xxhdpi/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | false
6 | false
7 | false
8 | true
9 | false
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values-xxxhdpi/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | false
6 | false
7 | false
8 | false
9 | true
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values/attrs_space_divider_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/lesscode-core/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | LessCode Core
3 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':lesscode-core'
2 |
--------------------------------------------------------------------------------