├── .gitignore
├── README.md
├── build.gradle
├── fastandroid
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── hunter
│ │ └── fastandroid
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── hunter
│ │ └── fastandroid
│ │ ├── app
│ │ ├── ActivityManager.java
│ │ ├── BaseApplication.java
│ │ ├── Constants.java
│ │ ├── DaoManager.java
│ │ ├── ServiceManager.java
│ │ ├── Setting.java
│ │ ├── URLs.java
│ │ └── UserManager.java
│ │ ├── base
│ │ ├── BaseActivity.java
│ │ ├── BaseFragment.java
│ │ ├── BasePresenter.java
│ │ ├── BaseRecyclerAdapter.java
│ │ ├── CustomBaseAdapter.java
│ │ ├── CustomFragmentPagerAdapter.java
│ │ ├── CustomPagerAdapter.java
│ │ ├── IBaseView.java
│ │ └── RecyclerViewHolder.java
│ │ ├── exception
│ │ ├── ApiException.java
│ │ └── CommonException.java
│ │ ├── presenter
│ │ └── TestPresenter.java
│ │ ├── rx
│ │ ├── CommonSubscriber.java
│ │ ├── JsonResponseFunc.java
│ │ ├── JsonResponseObserver.java
│ │ ├── ResponseObserver.java
│ │ └── ResponseSubscriber.java
│ │ ├── service
│ │ └── TestService.java
│ │ ├── ui
│ │ ├── activity
│ │ │ ├── LoginActivity.java
│ │ │ └── MainActivity.java
│ │ ├── adapter
│ │ │ └── BookAdapter.java
│ │ ├── interfaces
│ │ │ └── ITestView.java
│ │ └── widget
│ │ │ ├── CountDownButton.java
│ │ │ ├── CustomGridView.java
│ │ │ ├── CustomListView.java
│ │ │ ├── CustomProgress.java
│ │ │ ├── NoZoomControllWebView.java
│ │ │ └── TitleBar.java
│ │ ├── utils
│ │ ├── CommonUtils.java
│ │ ├── DateUtils.java
│ │ ├── DialogUtils.java
│ │ ├── FileInfoUtils.java
│ │ ├── ImageLoadUtils.java
│ │ ├── MyStringUtils.java
│ │ ├── NetUtils.java
│ │ ├── NumberUtils.java
│ │ ├── PixelUtils.java
│ │ ├── SdCardUtils.java
│ │ └── SystemUtils.java
│ │ └── vo
│ │ ├── Book.java
│ │ ├── DoubanResponse.java
│ │ ├── JsonResponse.java
│ │ ├── Page.java
│ │ └── User.java
│ └── res
│ ├── anim
│ ├── push_left_in.xml
│ ├── push_left_out.xml
│ ├── push_right_in.xml
│ └── push_right_out.xml
│ ├── drawable
│ └── bg_progress.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── common_header.xml
│ ├── common_header_leftbutton.xml
│ ├── common_header_rightbutton.xml
│ ├── include_title_bar.xml
│ ├── item_book.xml
│ ├── layout_back.xml
│ └── progress.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── nav_back.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── nav_back.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ └── values
│ ├── color.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── gradlew
├── gradlew.bat
├── res
├── alipay.jpg
└── wxpay.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 | gradle
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FastAndroid 2.1 因为简单,所以快速
2 |
官方交流群:310262562
3 | 如有疑问或建议,可联系作者微信:han54001 (请备注交流FA)
4 | 全新改版
5 |
6 | 1.图片加载库改为 glide
7 | 2.更新butterknife
8 | 3.加入Rxjava & retrofit
9 | 4.更改MVP结构,更加方便快捷
10 | 5.精简框架,更加轻便快捷
11 |
12 | 更新日志
13 |
14 | 2017.1.11
15 | 1.新增 GreenDao 3.2 支持
16 | 2.新增 RxLifecycle 支持
17 |
18 | 2017.6.20
19 | 1.新增演示代码(无法运行,仅作为使用演示)
20 |
21 | 2018.8.21
22 | 1.全新支持RxJava2.0
23 | 2.替换所有旧版本的依赖
24 | 3.剔除无用的demo
25 |
26 | 2018.8.27
27 | 1.使用"豆瓣图书Api V2--搜索图书"接口作为演示
28 |
29 | # 捐助
30 |
31 | FastAndroid 是免费开源项目,不会收取任何费用。作者维护这个项目需要耗费不少精力,如果FastAndroid帮到了你,你可以捐款让这个项目变得更好。当然,无论是否捐款,都感谢您对本项目的支持。
32 |
33 | **捐款是纯粹自愿的捐助行为,我将非常感谢您的捐助,但您本人并不会因为您的捐款而获得比其他不捐款用户更多的权利,望理解。**
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | mavenCentral() // add repository
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.3.0-alpha03'
12 | classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/fastandroid/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/fastandroid/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'org.greenrobot.greendao' // apply plugin
3 |
4 | android {
5 | compileSdkVersion 27
6 | defaultConfig {
7 | applicationId "com.hunter.fastandroid"
8 | minSdkVersion 18
9 | targetSdkVersion 26
10 | versionCode 201
11 | versionName "2.0.1"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | greendao{
20 | schemaVersion 1
21 | daoPackage 'cache.greendao'
22 | }
23 | }
24 |
25 |
26 | dependencies {
27 | implementation fileTree(dir: 'libs', include: ['*.jar'])
28 | implementation 'com.android.support:appcompat-v7:27.1.1'
29 | implementation 'com.android.support:recyclerview-v7:27.1.1'
30 | // Glide
31 | implementation 'com.github.bumptech.glide:glide:4.8.0'
32 | annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
33 | // Butterknife
34 | implementation 'com.jakewharton:butterknife:8.8.1'
35 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
36 | // RxJava
37 | implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
38 | // RxAndroid
39 | implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
40 | // RxLifecycle
41 | implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.2'
42 | // Retrofit
43 | implementation 'com.squareup.retrofit2:retrofit:2.4.0'
44 | implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
45 | implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
46 | // Okhttp
47 | implementation 'com.squareup.okhttp3:okhttp:3.11.0'
48 | implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
49 | // Gson
50 | implementation 'com.google.code.gson:gson:2.8.5'
51 | // GreenDao
52 | implementation 'org.greenrobot:greendao:3.2.2'
53 | // Logger
54 | implementation 'com.orhanobut:logger:2.2.0'
55 | // SystemBarTint
56 | implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
57 | // AVLoadingIndicatorView
58 | implementation 'com.wang.avi:library:2.1.3'
59 | }
60 |
--------------------------------------------------------------------------------
/fastandroid/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 D:\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 |
--------------------------------------------------------------------------------
/fastandroid/src/androidTest/java/com/hunter/fastandroid/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/fastandroid/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/ActivityManager.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | /**
4 | * Created by Administrator on 2017/6/7.
5 | */
6 |
7 | import android.app.Activity;
8 |
9 | import java.util.Stack;
10 |
11 | /**
12 | * activity管理类
13 | *
14 | */
15 | public class ActivityManager {
16 | /**
17 | * 接收activity的Stack
18 | */
19 | private static Stack activityStack = new Stack<>();
20 | private static ActivityManager activityManager = new ActivityManager();
21 |
22 | private ActivityManager(){}
23 |
24 | /**
25 | * 单实例
26 | *
27 | * @return
28 | */
29 | public static ActivityManager getInstance() {
30 | return activityManager;
31 | }
32 |
33 |
34 | /**
35 | * 将activity移出栈
36 | *
37 | * @param activity
38 | */
39 | public void popActivity(Activity activity) {
40 | if (activity != null) {
41 | activityStack.remove(activity);
42 | }
43 | }
44 |
45 | /**
46 | * 结束指定activity
47 | *
48 | * @param activity
49 | */
50 | public void endActivity(Activity activity) {
51 | if (activity != null) {
52 | activity.finish();
53 | activityStack.remove(activity);
54 | activity = null;
55 | }
56 | }
57 |
58 | /**
59 | * 获得当前的activity(即最上层)
60 | *
61 | * @return
62 | */
63 | public Activity currentActivity() {
64 | Activity activity = null;
65 | if (!activityStack.empty())
66 | activity = activityStack.lastElement();
67 | return activity;
68 | }
69 |
70 | /**
71 | * 将activity推入栈内
72 | *
73 | * @param activity
74 | */
75 | public void pushActivity(Activity activity) {
76 | if (activityStack == null) {
77 | activityStack = new Stack();
78 | }
79 | activityStack.add(activity);
80 | }
81 |
82 | /**
83 | * 弹出除cls外的所有activity
84 | *
85 | * @param cls
86 | */
87 | public void popAllActivityExceptOne(Class extends Activity> cls) {
88 | while (true) {
89 | Activity activity = currentActivity();
90 | if (activity == null) {
91 | break;
92 | }
93 | if (activity.getClass().equals(cls)) {
94 | break;
95 | }
96 | popActivity(activity);
97 | }
98 | }
99 |
100 | /**
101 | * 结束除cls之外的所有activity,执行结果都会清空Stack
102 | *
103 | * @param cls
104 | */
105 | public void finishAllActivityExceptOne(Class extends Activity> cls) {
106 | while (!activityStack.empty()) {
107 | Activity activity = currentActivity();
108 | if (activity.getClass().equals(cls)) {
109 | popActivity(activity);
110 | } else {
111 | endActivity(activity);
112 | }
113 | }
114 | }
115 |
116 | /**
117 | * 结束所有activity
118 | */
119 | public void finishAllActivity() {
120 | while (!activityStack.empty()) {
121 | Activity activity = currentActivity();
122 | endActivity(activity);
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import com.orhanobut.logger.AndroidLogAdapter;
7 | import com.orhanobut.logger.Logger;
8 |
9 | /**
10 | * 自定义应用入口
11 | *
12 | * @author Hunter
13 | */
14 | public class BaseApplication extends Application {
15 | private static BaseApplication mInstance;
16 |
17 | public static Context getInstance() {
18 | return mInstance;
19 | }
20 |
21 | @Override
22 | public void onCreate() {
23 | super.onCreate();
24 |
25 | mInstance = this;
26 |
27 | Logger.addLogAdapter(new AndroidLogAdapter());
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/Constants.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | /**
4 | * 全局变量存储类
5 | *
6 | * @author Hunter
7 | */
8 | public class Constants {
9 |
10 | // 数据库名称
11 | public static final String DATABASE_NAME = "leshow";
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/DaoManager.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | import cache.greendao.DaoMaster;
4 | import cache.greendao.DaoSession;
5 | import cache.greendao.UserDao;
6 |
7 | /**
8 | * GreenDao 操作管理器
9 | *
10 | * @author Hunter
11 | */
12 | public class DaoManager {
13 | private static DaoManager instance;
14 |
15 | private DaoSession daoSession;
16 |
17 | private DaoManager() {
18 | }
19 |
20 | public static DaoManager getInstance() {
21 | if (instance == null) {
22 | synchronized (DaoManager.class) {
23 | if (instance == null)
24 | instance = new DaoManager();
25 | }
26 | }
27 |
28 | return instance;
29 | }
30 |
31 | private DaoSession getDaoSession() {
32 | if (daoSession == null) {
33 | // 可在此自定义版本升级时的操作,当前默认为删除旧版本所有数据
34 | daoSession = DaoMaster.newDevSession(BaseApplication.getInstance(), Constants.DATABASE_NAME);
35 | }
36 |
37 | return daoSession;
38 | }
39 |
40 | public UserDao getUserDao() {
41 | return getDaoSession().getUserDao();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/ServiceManager.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | import com.hunter.fastandroid.utils.CommonUtils;
4 |
5 | import java.io.IOException;
6 | import java.util.TreeSet;
7 |
8 | import okhttp3.HttpUrl;
9 | import okhttp3.Interceptor;
10 | import okhttp3.OkHttpClient;
11 | import okhttp3.Request;
12 | import okhttp3.Response;
13 | import okhttp3.logging.HttpLoggingInterceptor;
14 | import retrofit2.Retrofit;
15 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
16 | import retrofit2.converter.gson.GsonConverterFactory;
17 |
18 | /**
19 | * Retrofit Service管理器
20 | *
21 | * @author Hunter
22 | */
23 | public class ServiceManager {
24 | private static ServiceManager instance;
25 |
26 | private ServiceManager() {
27 |
28 | }
29 |
30 | public static ServiceManager getInstance() {
31 | if (instance == null) {
32 | instance = new ServiceManager();
33 | }
34 |
35 | return instance;
36 | }
37 |
38 | public T getService(Class t) {
39 | return getService(URLs.BASE_URL, t);
40 | }
41 |
42 | public T getService(String baseUrl, Class t) {
43 | HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
44 | httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
45 | OkHttpClient.Builder builder = new OkHttpClient.Builder()
46 | .addInterceptor(httpLoggingInterceptor)
47 | .addInterceptor(new Interceptor() {
48 | @Override
49 | public Response intercept(Chain chain) throws IOException {
50 | Request request = chain.request();
51 |
52 | HttpUrl url = request.url();
53 | TreeSet sortParams = new TreeSet<>(url.queryParameterNames());
54 | StringBuilder stringBuilder = new StringBuilder();
55 |
56 | for(String param : sortParams){
57 | String paramValue = url.queryParameter(param);
58 | stringBuilder.append(param + ":" + paramValue + "&");
59 | }
60 |
61 | String sign = CommonUtils.EncryptMD5(stringBuilder.toString() + "abc123");
62 |
63 | Request build = request.newBuilder()
64 | .addHeader("appVersion", "")
65 | .addHeader("uid", "")
66 | .addHeader("time", "")
67 | .addHeader("sign", sign)
68 | .build();
69 |
70 | return chain.proceed(build);
71 | }
72 | });
73 |
74 | Retrofit retrofit = new Retrofit.Builder()
75 | .baseUrl(baseUrl)
76 | .client(builder.build())
77 | .addConverterFactory(GsonConverterFactory.create())
78 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
79 | .build();
80 |
81 | return retrofit.create(t);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/Setting.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.SharedPreferences;
6 | import android.content.SharedPreferences.Editor;
7 |
8 | /**
9 | * 配置文件操作类
10 | *
11 | * @author Hunter
12 | */
13 | public class Setting {
14 |
15 | private SharedPreferences mSharedPreferences;
16 | private Editor mEditor;
17 |
18 | public Setting(Context context, String name) {
19 | mSharedPreferences = context.getSharedPreferences(name,
20 | Activity.MODE_PRIVATE);
21 | }
22 |
23 | /**
24 | * 加载一个String数据
25 | *
26 | * @param key 目标数据的key
27 | * @return 目标数据, 无则返回空字符串
28 | */
29 | public String loadString(String key) {
30 | return mSharedPreferences.getString(key, "");
31 | }
32 |
33 | /**
34 | * 加载一个int类型的数据
35 | *
36 | * @param key 目标数据的key
37 | * @return 目标数据, 无则返回-1
38 | */
39 | public int loadInt(String key) {
40 | return mSharedPreferences.getInt(key, -1);
41 | }
42 |
43 | /**
44 | * 加载一个long类型的数据
45 | *
46 | * @param key 目标数据的key
47 | * @return 目标数据, 无则返回-1
48 | */
49 | public long loadLong(String key) {
50 | return mSharedPreferences.getLong(key, -1);
51 | }
52 |
53 | /**
54 | * 加载一个boolean类型的数据
55 | *
56 | * @param key 目标数据的key
57 | * @return 目标数据, 无则返回false
58 | */
59 | public boolean loadBoolean(String key) {
60 | return mSharedPreferences.getBoolean(key, false);
61 | }
62 |
63 | /**
64 | * 加载一个float类型的数据
65 | *
66 | * @param key 目标数据的key
67 | * @return 目标数据, 无则返回-1
68 | */
69 | public float loadFloat(String key) {
70 | return mSharedPreferences.getFloat(key, -1);
71 | }
72 |
73 | /**
74 | * 以k-v形式保存一个String数据
75 | */
76 | public void saveString(String key, String value) {
77 | if (mEditor == null)
78 | mEditor = mSharedPreferences.edit();
79 |
80 | mEditor.putString(key, value);
81 | mEditor.commit();
82 | }
83 |
84 | /**
85 | * 以k-v保存一个int类型的数据
86 | */
87 | public void saveInt(String key, int value) {
88 | if (mEditor == null)
89 | mEditor = mSharedPreferences.edit();
90 |
91 | mEditor.putInt(key, value);
92 | mEditor.commit();
93 | }
94 |
95 | /**
96 | * 以k-v保存一个long类型的数据
97 | */
98 | public void saveLong(String key, long value) {
99 | if (mEditor == null)
100 | mEditor = mSharedPreferences.edit();
101 |
102 | mEditor.putLong(key, value);
103 | mEditor.commit();
104 | }
105 |
106 | /**
107 | * 以k-v保存一个boolean类型的数据
108 | */
109 | public void saveBoolean(String key, boolean value) {
110 | if (mEditor == null)
111 | mEditor = mSharedPreferences.edit();
112 |
113 | mEditor.putBoolean(key, value);
114 | mEditor.commit();
115 | }
116 |
117 | /**
118 | * 以k-v保存一个float类型的数据
119 | */
120 | public void saveFloat(String key, float value) {
121 | if (mEditor == null)
122 | mEditor = mSharedPreferences.edit();
123 |
124 | mEditor.putFloat(key, value);
125 | mEditor.commit();
126 | }
127 |
128 | /**
129 | * 清空数据
130 | */
131 | public void clear() {
132 | if (mEditor == null)
133 | mEditor = mSharedPreferences.edit();
134 |
135 | mEditor.clear();
136 | mEditor.commit();
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/URLs.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | /**
4 | * URL路径处理类
5 | *
6 | * @author Hunter
7 | */
8 | public class URLs {
9 | public static final String BASE_URL = "https://api.douban.com/v2/";
10 | public static final String MODUEL_BOOK = "book";
11 |
12 | public static final String SEARCH = "/search";
13 | }
14 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/app/UserManager.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.app;
2 |
3 | import com.hunter.fastandroid.vo.User;
4 |
5 | import java.util.List;
6 |
7 | import cache.greendao.UserDao;
8 |
9 | /**
10 | * Created by Administrator on 2017/1/10.
11 | */
12 | public class UserManager {
13 | private static UserManager instance;
14 | private User currentUser;
15 |
16 | private UserManager() {
17 | }
18 |
19 | public static UserManager getInstance() {
20 | if (instance == null) {
21 | synchronized (UserManager.class) {
22 | if (instance == null)
23 | instance = new UserManager();
24 | }
25 | }
26 |
27 | return instance;
28 | }
29 |
30 | /**
31 | * 保存用户信息,该方法一般用于登录成功后调用 (用户数据先放入内存,然后序列化到本地.如果本地已存在,则更新)
32 | *
33 | * @param user
34 | */
35 | public void setCurrentUser(User user) {
36 | currentUser = user;
37 |
38 | DaoManager daoManager = DaoManager.getInstance();
39 | UserDao userDao = daoManager.getUserDao();
40 | userDao.insertOrReplace(user);
41 | }
42 |
43 | /**
44 | * 清空用户信息,包括内存以及本地的数据
45 | */
46 | public void clearUserInfo() {
47 | currentUser = null;
48 |
49 | DaoManager daoManager = DaoManager.getInstance();
50 | UserDao userDao = daoManager.getUserDao();
51 | userDao.deleteAll();
52 | }
53 |
54 | /**
55 | * 获取用户ID
56 | * @return
57 | */
58 | public String getCurrentUserID() {
59 | if (getCurrentUser() == null) return "";
60 |
61 | return String.valueOf(getCurrentUser().getId());
62 | }
63 |
64 |
65 | /**
66 | * 获取用户令牌
67 | * @return
68 | */
69 | public String getCurrentUserToken() {
70 | if (currentUser == null) return "";
71 |
72 | return currentUser.getUserToken();
73 | }
74 |
75 | /**
76 | * 当前是否已经登录
77 | *
78 | * @return
79 | */
80 | public boolean isLogin() {
81 | return getCurrentUser() != null;
82 | }
83 |
84 | /**
85 | * 获取当前用户信息
86 | * @return
87 | */
88 | public User getCurrentUser() {
89 | if (currentUser == null) {
90 | DaoManager daoManager = DaoManager.getInstance();
91 | UserDao userDao = daoManager.getUserDao();
92 | List users = userDao.loadAll();
93 | if (users != null && users.size() > 0) {
94 | currentUser = users.get(0);
95 | }
96 | }
97 |
98 | return currentUser;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.view.Window;
12 | import android.view.WindowManager;
13 | import android.widget.Toast;
14 |
15 | import com.hunter.fastandroid.R;
16 | import com.hunter.fastandroid.app.ActivityManager;
17 | import com.hunter.fastandroid.app.UserManager;
18 | import com.hunter.fastandroid.ui.activity.LoginActivity;
19 | import com.hunter.fastandroid.ui.activity.MainActivity;
20 | import com.hunter.fastandroid.ui.widget.CustomProgress;
21 | import com.hunter.fastandroid.utils.CommonUtils;
22 | import com.readystatesoftware.systembartint.SystemBarTintManager;
23 | import com.trello.rxlifecycle2.LifecycleTransformer;
24 | import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
25 |
26 | import java.util.concurrent.TimeUnit;
27 |
28 | import butterknife.ButterKnife;
29 | import io.reactivex.Observable;
30 | import io.reactivex.Observer;
31 | import io.reactivex.android.schedulers.AndroidSchedulers;
32 | import io.reactivex.schedulers.Schedulers;
33 |
34 | /**
35 | * Activity基类
36 | *
37 | * @author Hunter
38 | */
39 | public abstract class BaseActivity extends RxAppCompatActivity implements IBaseView {
40 | private Toast toast;
41 | private ProgressDialog mProgressDialog;
42 |
43 | /**
44 | * 填充一个后退按钮
45 | *
46 | * @return
47 | */
48 | public View fillBackButton() {
49 | return fillBackButton(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View v) {
52 | close();
53 | }
54 | });
55 | }
56 |
57 | /**
58 | * 填充一个后退按钮
59 | *
60 | * @return
61 | */
62 | public View fillBackButton(View.OnClickListener onClickListener) {
63 | View backButton = View.inflate(this, R.layout.layout_back, null);
64 |
65 | backButton.setOnClickListener(onClickListener);
66 |
67 | return backButton;
68 | }
69 |
70 | /**
71 | * 初始化控件
72 | */
73 | public abstract void initView();
74 |
75 | /**
76 | * 初始化控制中心
77 | */
78 | public abstract void initPresenter();
79 |
80 | @Override
81 | protected void onCreate(Bundle savedInstanceState) {
82 | super.onCreate(savedInstanceState);
83 | setContentView(getContentResId());
84 | initStatusBar();
85 | // 初始化View注入
86 | ButterKnife.bind(this);
87 | initPresenter();
88 | initView();
89 |
90 | ActivityManager.getInstance().pushActivity(this);
91 | }
92 |
93 | public void goHome() {
94 | CommonUtils.hideSoftInput(this);
95 | finish();
96 | openPage(MainActivity.class);
97 | ActivityManager.getInstance().finishAllActivityExceptOne(MainActivity.class);
98 | }
99 |
100 | public void backHome() {
101 | finish();
102 | ActivityManager.getInstance().finishAllActivityExceptOne(MainActivity.class);
103 | }
104 |
105 | /**
106 | * 是否启用沉浸式
107 | *
108 | * @return
109 | */
110 | public boolean isImmersion() {
111 | return true;
112 | }
113 |
114 | /**
115 | * 初始化沉侵式状态栏
116 | */
117 | public void initStatusBar() {
118 | if (isImmersion()) {
119 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
120 | Window window = getWindow();
121 | // Translucent status bar
122 | window.setFlags(
123 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
124 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
125 | ViewGroup contentLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
126 | View parentView = contentLayout.getChildAt(0);
127 | if (parentView != null) {
128 | parentView.setFitsSystemWindows(true);
129 | }
130 | }
131 |
132 | initStatsBarColor();
133 | }
134 | }
135 |
136 | /**
137 | * 获取状态栏高度
138 | *
139 | * @return
140 | */
141 | public int getStatusBarHeight() {
142 | int result = 0;
143 | int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
144 | if (resourceId > 0) {
145 | result = getResources().getDimensionPixelSize(resourceId);
146 | }
147 | return result;
148 | }
149 |
150 | public void initStatsBarColor() {
151 | initStatsBarColor(0);
152 | }
153 |
154 | public void initStatsBarColor(int color) {
155 | SystemBarTintManager systemBarTintManager = new SystemBarTintManager(this);
156 | systemBarTintManager.setStatusBarTintEnabled(true);
157 | if (color == 0) {
158 | systemBarTintManager.setStatusBarTintResource(R.color.colorPrimary);
159 | } else {
160 | systemBarTintManager.setStatusBarTintResource(color);
161 | }
162 | }
163 |
164 | protected abstract int getContentResId();
165 |
166 | @Override
167 | public Context getContext() {
168 | return this;
169 | }
170 |
171 | @Override
172 | public void finish() {
173 | super.finish();
174 | ActivityManager.getInstance().popActivity(this);
175 | }
176 |
177 | @Override
178 | public void showProgress(final boolean flag, final String message) {
179 | showLoading(flag, message);
180 | }
181 |
182 | private void showLoading(boolean flag, String message) {
183 | if (mProgressDialog == null) {
184 | mProgressDialog = new CustomProgress(this, R.style.CustomDialog);
185 | mProgressDialog.setCanceledOnTouchOutside(false);
186 | }
187 | mProgressDialog.setCancelable(flag);
188 | mProgressDialog.setMessage(message);
189 |
190 | if(!mProgressDialog.isShowing()){
191 | mProgressDialog.show();
192 | }
193 | }
194 |
195 | @Override
196 | public void showProgress(String message) {
197 | showProgress(true, message);
198 | }
199 |
200 | @Override
201 | public void showProgress(int strRes) {
202 | showProgress(getString(strRes));
203 | }
204 |
205 | @Override
206 | public void hideProgress() {
207 | if (mProgressDialog == null)
208 | return;
209 |
210 | if (mProgressDialog.isShowing()) {
211 | mProgressDialog.dismiss();
212 | }
213 | }
214 |
215 | @Override
216 | public void setProgressCancelListener(DialogInterface.OnCancelListener onCancelListener) {
217 | if (mProgressDialog != null) {
218 | mProgressDialog.setOnCancelListener(onCancelListener);
219 | }
220 | }
221 |
222 | @Override
223 | public void showToast(String msg) {
224 | if (!isFinishing()) {
225 | if (toast == null) {
226 | toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
227 | } else {
228 | toast.setText(msg);
229 | }
230 |
231 | toast.show();
232 | }
233 | }
234 |
235 | @Override
236 | public void showToast(int res) {
237 | showToast(getString(res));
238 | }
239 |
240 | @Override
241 | public void openPage(Class clazz) {
242 | openPage(new Intent(this, clazz));
243 | }
244 |
245 | public void finishAndOpenPage(Class clazz){
246 | finish();
247 | openPage(clazz);
248 | }
249 |
250 | @Override
251 | public void openPage(Intent intent) {
252 | startActivity(intent);
253 | overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
254 | }
255 |
256 | @Override
257 | public void openPageForResult(Intent intent, int requestCode) {
258 | startActivityForResult(intent, requestCode);
259 | overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
260 | }
261 |
262 | @Override
263 | public void close() {
264 | finish();
265 | overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
266 | }
267 |
268 | /**
269 | * 开始执行一个延时任务
270 | * @param delay
271 | * @param unit
272 | * @param observer
273 | */
274 | @Override
275 | public void startDelayAsync(long delay, TimeUnit unit, Observer observer) {
276 | startAsync(Observable.timer(delay, unit), observer);
277 | }
278 |
279 | /**
280 | * 开始执行一个定时任务
281 | * @param period
282 | * @param unit
283 | * @param observer
284 | */
285 | @Override
286 | public void startIntervalAsync(long period, TimeUnit unit, Observer observer) {
287 | startAsync(Observable.interval(period, unit), observer);
288 | }
289 |
290 | /**
291 | * 开始执行一个异步任务
292 | *
293 | * @param observable
294 | * @param observer
295 | * @param
296 | */
297 | @Override
298 | public void startAsync(Observable observable, Observer observer) {
299 | observable
300 | .subscribeOn(Schedulers.io())
301 | .unsubscribeOn(Schedulers.io())
302 | .observeOn(AndroidSchedulers.mainThread())
303 | .compose(this.bind())
304 | .subscribe(observer);
305 | }
306 |
307 | @Override
308 | public void clearUser() {
309 | UserManager.getInstance().clearUserInfo();
310 | openPage(LoginActivity.class);
311 | ActivityManager.getInstance().finishAllActivityExceptOne(LoginActivity.class);
312 | }
313 |
314 | @Override
315 | public LifecycleTransformer bind() {
316 | return bindToLifecycle();
317 | }
318 | }
319 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.content.Context;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import com.hunter.fastandroid.R;
12 | import com.trello.rxlifecycle2.LifecycleTransformer;
13 | import com.trello.rxlifecycle2.components.support.RxFragment;
14 |
15 | import java.util.concurrent.TimeUnit;
16 |
17 | import butterknife.ButterKnife;
18 | import io.reactivex.Observable;
19 | import io.reactivex.Observer;
20 | import io.reactivex.android.schedulers.AndroidSchedulers;
21 | import io.reactivex.schedulers.Schedulers;
22 |
23 | /**
24 | * Fragment基类
25 | *
26 | * @author Hunter
27 | */
28 | public abstract class BaseFragment extends RxFragment implements IBaseView {
29 | private View mLayoutView;
30 |
31 | /**
32 | * 初始化布局
33 | */
34 | public abstract int getLayoutRes();
35 |
36 | /**
37 | * 初始化视图
38 | */
39 | public abstract void initView();
40 |
41 | @Override
42 | public Context getContext() {
43 | return getBaseActivity().getContext();
44 | }
45 |
46 | @Override
47 | public void onCreate(Bundle savedInstanceState) {
48 | super.onCreate(savedInstanceState);
49 | }
50 |
51 | @Override
52 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
53 | if (mLayoutView != null) {
54 | ViewGroup parent = (ViewGroup) mLayoutView.getParent();
55 | if (parent != null) {
56 | parent.removeView(mLayoutView);
57 | }
58 | } else {
59 | mLayoutView = getCreateView(inflater, container);
60 | ButterKnife.bind(this, mLayoutView);
61 | initView(); //初始化布局
62 | }
63 |
64 | return mLayoutView;
65 | }
66 |
67 | /**
68 | * 获取Fragment布局文件的View
69 | *
70 | * @param inflater
71 | * @param container
72 | * @return
73 | */
74 | private View getCreateView(LayoutInflater inflater, ViewGroup container) {
75 | return inflater.inflate(getLayoutRes(), container, false);
76 | }
77 |
78 | /**
79 | * 获取当前Fragment状态
80 | *
81 | * @return true为正常 false为未加载或正在删除
82 | */
83 | private boolean getStatus() {
84 | return (isAdded() && !isRemoving());
85 | }
86 |
87 | /**
88 | * 获取Activity
89 | *
90 | * @return
91 | */
92 | public BaseActivity getBaseActivity() {
93 | return (BaseActivity) getActivity();
94 | }
95 |
96 | @Override
97 | public void showProgress(boolean flag, String message) {
98 | if (getStatus()) {
99 | getBaseActivity().showProgress(flag, message);
100 | }
101 | }
102 |
103 | @Override
104 | public void showProgress(String message) {
105 | showProgress(true, message);
106 | }
107 |
108 | @Override
109 | public void showProgress(int strRes) {
110 | showProgress(getString(strRes));
111 | }
112 |
113 | @Override
114 | public void hideProgress() {
115 | if (getStatus()) {
116 | getBaseActivity().hideProgress();
117 | }
118 | }
119 |
120 | @Override
121 | public void setProgressCancelListener(DialogInterface.OnCancelListener onCancelListener) {
122 | getBaseActivity().setProgressCancelListener(onCancelListener);
123 | }
124 |
125 | @Override
126 | public void showToast(String msg) {
127 | if (getStatus()) {
128 | getBaseActivity().showToast(msg);
129 | }
130 | }
131 |
132 | @Override
133 | public void showToast(int res) {
134 | showToast(getString(res));
135 | }
136 |
137 | @Override
138 | public void openPage(Class clazz) {
139 | getBaseActivity().openPage(clazz);
140 | }
141 |
142 | @Override
143 | public void openPage(Intent intent) {
144 | getBaseActivity().openPage(intent);
145 | }
146 |
147 | @Override
148 | public void openPageForResult(Intent intent, int requestCode) {
149 | startActivityForResult(intent, requestCode);
150 | getBaseActivity().overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
151 | }
152 |
153 | @Override
154 | public void close() {
155 | getBaseActivity().close();
156 | }
157 |
158 | @Override
159 | public void startAsync(Observable observable, Observer observer) {
160 | observable
161 | .subscribeOn(Schedulers.io())
162 | .unsubscribeOn(Schedulers.io())
163 | .observeOn(AndroidSchedulers.mainThread())
164 | .compose(this.bind())
165 | .subscribe(observer);
166 | }
167 |
168 | @Override
169 | public void clearUser() {
170 | getBaseActivity().clearUser();
171 | }
172 |
173 | @Override
174 | public LifecycleTransformer bind() {
175 | return bindToLifecycle();
176 | }
177 |
178 | @Override
179 | public void startDelayAsync(long delay, TimeUnit unit, Observer observer) {
180 | startAsync(Observable.timer(delay, unit), observer);
181 | }
182 |
183 | @Override
184 | public void startIntervalAsync(long period, TimeUnit unit, Observer observer) {
185 | startAsync(Observable.interval(period, unit), observer);
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.hunter.fastandroid.R;
6 | import com.hunter.fastandroid.app.ServiceManager;
7 | import com.hunter.fastandroid.rx.JsonResponseFunc;
8 | import com.hunter.fastandroid.utils.MyStringUtils;
9 | import com.hunter.fastandroid.vo.JsonResponse;
10 |
11 | import org.reactivestreams.Subscriber;
12 |
13 | import java.lang.reflect.Field;
14 | import java.util.Collections;
15 | import java.util.HashMap;
16 | import java.util.Map;
17 |
18 | import io.reactivex.Flowable;
19 | import io.reactivex.Observable;
20 | import io.reactivex.Observer;
21 | import io.reactivex.android.schedulers.AndroidSchedulers;
22 | import io.reactivex.schedulers.Schedulers;
23 |
24 |
25 | /**
26 | * Presenter基类
27 | *
28 | * @author Hunter
29 | */
30 | public abstract class BasePresenter {
31 |
32 | public BasePresenter() {
33 | initService();
34 | }
35 |
36 | protected abstract void initService();
37 |
38 | public T getService(Class clazz) {
39 | ServiceManager serviceManager = ServiceManager.getInstance();
40 | return serviceManager.getService(clazz);
41 | }
42 |
43 | /**
44 | * 普通简单订阅
45 | * @param view
46 | * @param observable
47 | * @param observer
48 | * @param
49 | */
50 | public void subscribe(IBaseView view, Observable observable, Observer observer) {
51 | observable
52 | .subscribeOn(Schedulers.io())
53 | .unsubscribeOn(Schedulers.io())
54 | .observeOn(AndroidSchedulers.mainThread())
55 | .compose(view.bind())
56 | .subscribe(observer);
57 | }
58 |
59 | /**
60 | * 转换响应实体的类型
61 | *
62 | * @param observable
63 | * @param
64 | * @return
65 | */
66 | public Observable convertResponse(Observable> observable) {
67 | return observable.map(new JsonResponseFunc());
68 | }
69 |
70 | /**
71 | * 转换请求实体类
72 | *
73 | * @param object
74 | * @return
75 | */
76 | public Map converParams(Object object) {
77 | if (object == null) return Collections.emptyMap();
78 |
79 | Class clazz = object.getClass();
80 | Class superclass = clazz.getSuperclass();
81 |
82 | Field[] fields = clazz.getDeclaredFields();
83 | Field[] superFields = superclass.getDeclaredFields();
84 |
85 | if (fields == null || fields.length == 0) {
86 | return Collections.emptyMap();
87 | }
88 |
89 | Map params = new HashMap();
90 | try {
91 | for (Field field : fields) {
92 | field.setAccessible(true);
93 | if(field.get(object) != null){
94 | params.put(field.getName(), String.valueOf(field.get(object)));
95 | }
96 | }
97 |
98 | for (Field superField : superFields) {
99 | superField.setAccessible(true);
100 | if(superField.get(object) != null) {
101 | params.put(superField.getName(), String.valueOf(superField.get(object)));
102 | }
103 | }
104 |
105 | } catch (IllegalAccessException e) {
106 | e.printStackTrace();
107 | } catch (IllegalArgumentException e) {
108 | e.printStackTrace();
109 | }
110 |
111 | return params;
112 | }
113 |
114 | /**
115 | * 校验字符串是否为空
116 | * @param baseView
117 | * @param content 需要校验的内容
118 | * @param strRes 为空时的提示语
119 | * @return
120 | */
121 | public boolean isEmpty(IBaseView baseView, String content, int strRes) {
122 | if (TextUtils.isEmpty(content)) {
123 | baseView.showToast(strRes);
124 | return true;
125 | }
126 |
127 | return false;
128 | }
129 |
130 | /**
131 | * 校验字符串是否为空
132 | * @param baseView
133 | * @param content 需要校验的内容
134 | * @param str 为空时的提示语
135 | * @return
136 | */
137 | public boolean isEmpty(IBaseView baseView, String content, String str) {
138 | if (TextUtils.isEmpty(content)) {
139 | baseView.showToast(str);
140 | return true;
141 | }
142 |
143 | return false;
144 | }
145 |
146 | /**
147 | * 校验手机号是否有效
148 | * @param baseview
149 | * @param mobile
150 | * @return
151 | */
152 | public boolean isMobile(IBaseView baseview, String mobile){
153 | if(!MyStringUtils.checkCellphone(mobile)){
154 | baseview.showToast(R.string.mobile_valid);
155 | return false;
156 | }
157 |
158 | return true;
159 | }
160 |
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/BaseRecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.LayoutRes;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by Administrator on 2017/1/16.
14 | */
15 | public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter {
16 | private List mDatas;
17 | private Context mContext;
18 | private LayoutInflater mInflater;
19 | private OnItemClickListener mOnItemClickListener;
20 |
21 | public BaseRecyclerAdapter(Context context) {
22 | this.mContext = context;
23 | mInflater = (LayoutInflater) mContext
24 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
25 | }
26 |
27 | @Override
28 | public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
29 | View view = mInflater.inflate(getLayoutId(), parent, false);
30 | return new RecyclerViewHolder(view);
31 | }
32 |
33 | @Override
34 | public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
35 | holder.itemView.setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View v) {
38 | if (mOnItemClickListener != null) mOnItemClickListener.onItemClick(position);
39 | }
40 | });
41 |
42 | bindView(holder, position);
43 | }
44 |
45 | abstract public void bindView(RecyclerViewHolder holder, final int position);
46 |
47 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
48 | mOnItemClickListener = onItemClickListener;
49 | }
50 |
51 | @LayoutRes
52 | abstract public int getLayoutId();
53 |
54 | /**
55 | * 获取上下文对象
56 | *
57 | * @return
58 | */
59 | public Context getContext() {
60 | return mContext;
61 | }
62 |
63 | @Override
64 | public int getItemCount() {
65 | return mDatas == null ? 0 : mDatas.size();
66 | }
67 |
68 | /**
69 | * 获取指定item数据
70 | *
71 | * @param position
72 | * @return
73 | */
74 | public T getItemData(int position) {
75 | return mDatas == null ? null : mDatas.get(position);
76 | }
77 |
78 | /**
79 | * 获取数据集合
80 | *
81 | * @return
82 | */
83 | public List getData() {
84 | return mDatas;
85 | }
86 |
87 | /**
88 | * 设置数据集合
89 | *
90 | * @param datas
91 | */
92 | public void setData(List datas) {
93 | this.mDatas = datas;
94 | }
95 |
96 | /**
97 | * 移除指定item的数据
98 | *
99 | * @param position
100 | */
101 | public void removeData(int position) {
102 | this.mDatas.remove(position);
103 | }
104 |
105 | public interface OnItemClickListener {
106 | void onItemClick(int position);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/CustomBaseAdapter.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 自定义适配器
13 | *
14 | * @param 数据集合类型
15 | * @author Hunter
16 | */
17 | public abstract class CustomBaseAdapter extends BaseAdapter {
18 | private LayoutInflater mInflater;
19 | private List mDatas;
20 | private Context mContext;
21 |
22 | public CustomBaseAdapter(Context context) {
23 | mContext = context;
24 | mInflater = (LayoutInflater) mContext
25 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
26 | }
27 |
28 | /**
29 | * 获取上下文对象
30 | *
31 | * @return
32 | */
33 | public Context getContext() {
34 | return mContext;
35 | }
36 |
37 | /**
38 | * 获取item布局
39 | *
40 | * @return
41 | */
42 | public View getItemView(int resource, ViewGroup parent) {
43 | return mInflater.inflate(resource, parent, false);
44 | }
45 |
46 | /**
47 | * 获取指定item数据
48 | *
49 | * @param position
50 | * @return
51 | */
52 | public T getItemData(int position) {
53 | return mDatas == null ? null : mDatas.get(position);
54 | }
55 |
56 | /**
57 | * 获取数据集合
58 | *
59 | * @return
60 | */
61 | public List getData() {
62 | return mDatas;
63 | }
64 |
65 | /**
66 | * 设置数据集合
67 | *
68 | * @param datas
69 | */
70 | public void setData(List datas) {
71 | this.mDatas = datas;
72 | }
73 |
74 | /**
75 | * 移除指定item的数据
76 | *
77 | * @param position
78 | */
79 | public void removeData(int position) {
80 | this.mDatas.remove(position);
81 | }
82 |
83 | @Override
84 | public int getCount() {
85 | return mDatas == null ? 0 : mDatas.size();
86 | }
87 |
88 | @Override
89 | public Object getItem(int position) {
90 | return mDatas == null ? null : mDatas.get(position);
91 | }
92 |
93 | @Override
94 | public long getItemId(int position) {
95 | return 0;
96 | }
97 |
98 | @Override
99 | public abstract View getView(int position, View convertView, ViewGroup parent);
100 | }
101 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/CustomFragmentPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | /**
11 | * 自定义Fragment页面适配器
12 | *
13 | * @author Hunter
14 | */
15 | public class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
16 | List mFragments;
17 | List mTitles;
18 |
19 | public CustomFragmentPagerAdapter(FragmentManager fm) {
20 | super(fm);
21 | }
22 |
23 | /**
24 | * 设置当前adapter的页面集合
25 | *
26 | * @param fragments
27 | */
28 | public void setPagers(List fragments) {
29 | mFragments = fragments;
30 | }
31 |
32 | /**
33 | * 添加一个页面
34 | *
35 | * @param fragment
36 | */
37 | public void addPager(Fragment fragment) {
38 | if (mFragments == null) {
39 | ArrayList fragments = new ArrayList();
40 | fragments.add(fragment);
41 | setPagers(fragments);
42 | } else {
43 | mFragments.add(fragment);
44 | }
45 | }
46 |
47 | /**
48 | * 添加一组页面
49 | *
50 | * @param fragments
51 | */
52 | public void addPagers(List fragments) {
53 | if (mFragments == null) {
54 | setPagers(fragments);
55 | } else {
56 | mFragments.addAll(fragments);
57 | }
58 | }
59 |
60 | /**
61 | * 设置页面的标题
62 | *
63 | * @param titles
64 | */
65 | public void setTitles(List titles) {
66 | mTitles = titles;
67 | }
68 |
69 | /**
70 | * 添加一个页面的标题
71 | *
72 | * @param title
73 | */
74 | public void addTitle(String title) {
75 | if (mTitles == null) {
76 | ArrayList titles = new ArrayList();
77 | titles.add(title);
78 | setTitles(titles);
79 | } else {
80 | mTitles.add(title);
81 | }
82 | }
83 |
84 | /**
85 | * 添加一组页面的标题
86 | *
87 | * @param titles
88 | */
89 | public void addTitles(List titles) {
90 | if (mTitles == null) {
91 | setTitles(titles);
92 | } else {
93 | mTitles.addAll(titles);
94 | }
95 | }
96 |
97 | @Override
98 | public CharSequence getPageTitle(int position) {
99 | return mTitles == null ? null : mTitles.get(position);
100 | }
101 |
102 | @Override
103 | public Fragment getItem(int position) {
104 | return mFragments == null ? null : mFragments.get(position);
105 | }
106 |
107 | @Override
108 | public int getCount() {
109 | return mFragments == null ? 0 : mFragments.size();
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/CustomPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | /**
11 | * 自定义Fragment页面适配器
12 | *
13 | * @author Hunter
14 | */
15 | public class CustomPagerAdapter extends FragmentPagerAdapter {
16 | List mFragments;
17 | List mTitles;
18 |
19 | public CustomPagerAdapter(FragmentManager fm) {
20 | super(fm);
21 | }
22 |
23 | /**
24 | * 设置当前adapter的页面集合
25 | *
26 | * @param fragments
27 | */
28 | public void setPagers(List fragments) {
29 | mFragments = fragments;
30 | }
31 |
32 | /**
33 | * 添加一个页面
34 | *
35 | * @param fragment
36 | */
37 | public void addPager(Fragment fragment) {
38 | if (mFragments == null) {
39 | ArrayList fragments = new ArrayList();
40 | fragments.add(fragment);
41 | setPagers(fragments);
42 | } else {
43 | mFragments.add(fragment);
44 | }
45 | }
46 |
47 | /**
48 | * 添加一组页面
49 | *
50 | * @param fragments
51 | */
52 | public void addPagers(List fragments) {
53 | if (mFragments == null) {
54 | setPagers(fragments);
55 | } else {
56 | mFragments.addAll(fragments);
57 | }
58 | }
59 |
60 | /**
61 | * 设置页面的标题
62 | *
63 | * @param titles
64 | */
65 | public void setTitles(List titles) {
66 | mTitles = titles;
67 | }
68 |
69 | /**
70 | * 添加一个页面的标题
71 | *
72 | * @param title
73 | */
74 | public void addTitle(String title) {
75 | if (mTitles == null) {
76 | ArrayList titles = new ArrayList();
77 | titles.add(title);
78 | setTitles(titles);
79 | } else {
80 | mTitles.add(title);
81 | }
82 | }
83 |
84 | /**
85 | * 添加一组页面的标题
86 | *
87 | * @param titles
88 | */
89 | public void addTitles(List titles) {
90 | if (mTitles == null) {
91 | setTitles(titles);
92 | } else {
93 | mTitles.addAll(titles);
94 | }
95 | }
96 |
97 | @Override
98 | public CharSequence getPageTitle(int position) {
99 | return mTitles == null ? null : mTitles.get(position);
100 | }
101 |
102 | @Override
103 | public Fragment getItem(int position) {
104 | return mFragments == null ? null : mFragments.get(position);
105 | }
106 |
107 | @Override
108 | public int getCount() {
109 | return mFragments == null ? 0 : mFragments.size();
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.content.Context;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 |
7 | import com.trello.rxlifecycle2.LifecycleTransformer;
8 |
9 | import java.util.concurrent.TimeUnit;
10 |
11 | import io.reactivex.Observable;
12 | import io.reactivex.Observer;
13 |
14 |
15 | /**
16 | * View层接口基类
17 | *
18 | * @author Hunter
19 | */
20 | public interface IBaseView {
21 |
22 | /**
23 | * 获取上下文对象
24 | * @return
25 | */
26 | Context getContext();
27 |
28 | /**
29 | * 显示进度条
30 | *
31 | * @param flag 是否可取消
32 | * @param message 要显示的信息
33 | */
34 | void showProgress(boolean flag, String message);
35 |
36 | /**
37 | * 显示可取消的进度条
38 | *
39 | * @param message 要显示的信息
40 | */
41 | void showProgress(String message);
42 |
43 | /**
44 | * 显示可取消的进度条
45 | * @param strRes
46 | */
47 | void showProgress(int strRes);
48 |
49 | /**
50 | * 隐藏进度条
51 | */
52 | void hideProgress();
53 |
54 | /**
55 | * 设置取消进度条监听
56 | *
57 | * @param onCancelListener
58 | */
59 | void setProgressCancelListener(DialogInterface.OnCancelListener onCancelListener);
60 |
61 | /**
62 | * 根据字符串弹出toast
63 | *
64 | * @param msg 提示内容
65 | */
66 | void showToast(String msg);
67 |
68 | /**
69 | * 根据字符串资源弹出toast
70 | * @param res
71 | */
72 | void showToast(int res);
73 |
74 | /**
75 | * 打开指定页面
76 | * @param clazz
77 | */
78 | void openPage(Class clazz);
79 |
80 | /**
81 | * 根据意图打开页面
82 | * @param intent
83 | */
84 | void openPage(Intent intent);
85 |
86 | /**
87 | * 带请求的打开页面
88 | * @param intent
89 | * @param requestCode
90 | */
91 | void openPageForResult(Intent intent, int requestCode);
92 |
93 | /**
94 | * 关闭当前页面
95 | */
96 | void close();
97 |
98 | /**
99 | * 开始执行一个延时任务
100 | * @param delay
101 | * @param unit
102 | * @param observer
103 | */
104 | void startDelayAsync(long delay, TimeUnit unit, Observer observer);
105 |
106 | /**
107 | * 开始执行一个定时任务
108 | * @param period
109 | * @param unit
110 | * @param observer
111 | */
112 | void startIntervalAsync(long period, TimeUnit unit, Observer observer);
113 |
114 | /**
115 | * 执行一个基于rxjava的异步任务
116 | * @param observable
117 | */
118 | void startAsync(Observable observable, Observer observer);
119 |
120 | /**
121 | * 清除当前登录用户,并跳转到登录界面
122 | */
123 | void clearUser();
124 |
125 | /**
126 | * 关联RxLifecycle
127 | *
128 | * @param
129 | * @return
130 | */
131 | LifecycleTransformer bind();
132 | }
133 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/base/RecyclerViewHolder.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.base;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.util.SparseArray;
5 | import android.view.View;
6 |
7 | /**
8 | * Created by Administrator on 2017/1/16.
9 | */
10 | public class RecyclerViewHolder extends RecyclerView.ViewHolder {
11 | private SparseArray arrayView;
12 |
13 | public RecyclerViewHolder(View itemView) {
14 | super(itemView);
15 | arrayView = new SparseArray<>();
16 | }
17 |
18 | /**
19 | * 通过填写的itemId来获取具体的View的对象
20 | * @param itemId R.id.***
21 | * @param 必须是View的子类
22 | * @return
23 | */
24 | public T getView(int itemId){
25 | //arrayVie类似于Map容器,get(key)取出的是value值
26 | View mView = arrayView.get(itemId);
27 | if(mView == null){
28 | //实例化具体的View类型
29 | mView = itemView.findViewById(itemId);
30 | arrayView.put(itemId,mView);
31 | }
32 | return (T) mView;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/exception/ApiException.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.exception;
2 |
3 |
4 | import com.hunter.fastandroid.vo.JsonResponse;
5 |
6 | /**
7 | * 自定义异常
8 | *
9 | * @author Hunter
10 | */
11 | public class ApiException extends RuntimeException {
12 | private JsonResponse tJsonResponse;
13 |
14 | public ApiException(JsonResponse jsonResponse) {
15 | super(jsonResponse.getMessage());
16 | tJsonResponse = jsonResponse;
17 | }
18 |
19 | public void setJsonResponse(JsonResponse jsonResponse) {
20 | tJsonResponse = jsonResponse;
21 | }
22 |
23 | public JsonResponse getJsonResponse() {
24 | return tJsonResponse;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/exception/CommonException.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.exception;
2 |
3 | /**
4 | * 自定义异常
5 | *
6 | * @author Hunter
7 | */
8 | public class CommonException extends RuntimeException {
9 | private String mErrorMsg;
10 |
11 | public CommonException(String errorMsg) {
12 | mErrorMsg = errorMsg;
13 | }
14 |
15 | @Override
16 | public String getMessage() {
17 | return mErrorMsg;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/presenter/TestPresenter.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.presenter;
2 |
3 | import com.hunter.fastandroid.base.BasePresenter;
4 | import com.hunter.fastandroid.rx.ResponseObserver;
5 | import com.hunter.fastandroid.service.TestService;
6 | import com.hunter.fastandroid.ui.interfaces.ITestView;
7 | import com.hunter.fastandroid.vo.DoubanResponse;
8 |
9 |
10 | /**
11 | * Created by Administrator on 2017/1/4.
12 | */
13 | public class TestPresenter extends BasePresenter {
14 | TestService service;
15 |
16 | @Override
17 | protected void initService() {
18 | service = getService(TestService.class);
19 | }
20 |
21 | public void test(String keyword, final ITestView testView) {
22 |
23 | subscribe(testView, service.test(keyword), new ResponseObserver(testView) {
24 | @Override
25 | public void onNext(DoubanResponse response) {
26 | testView.showData(response.getBooks());
27 | }
28 | });
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/rx/CommonSubscriber.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.rx;
2 |
3 |
4 | import com.hunter.fastandroid.base.IBaseView;
5 | import com.hunter.fastandroid.exception.CommonException;
6 | import com.orhanobut.logger.Logger;
7 |
8 | import io.reactivex.Observer;
9 | import io.reactivex.disposables.Disposable;
10 |
11 |
12 | /**
13 | * RxJava 自定义Subscriber
14 | *
15 | * @param
16 | * @author Hunter
17 | */
18 | public abstract class CommonSubscriber implements Observer {
19 | private IBaseView mBaseView;
20 | // 是否显示加载进度条
21 | private boolean mIsShowLoading = true;
22 |
23 | public CommonSubscriber(IBaseView baseView) {
24 | mBaseView = baseView;
25 | }
26 |
27 | public CommonSubscriber(IBaseView baseView, boolean isShowLoading) {
28 | mBaseView = baseView;
29 | mIsShowLoading = isShowLoading;
30 | }
31 |
32 | @Override
33 | public void onSubscribe(Disposable d) {
34 | if (mIsShowLoading) mBaseView.showProgress("加载中···");
35 | }
36 |
37 | @Override
38 | public void onError(Throwable e) {
39 | mBaseView.hideProgress();
40 |
41 | if (e instanceof CommonException) {
42 | mBaseView.showToast(e.getMessage());
43 | }else{
44 | Logger.e(e.getMessage());
45 | mBaseView.showToast("系统异常,请重试");
46 | }
47 | }
48 |
49 | @Override
50 | public void onComplete() {
51 | mBaseView.hideProgress();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/rx/JsonResponseFunc.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.rx;
2 |
3 |
4 | import com.hunter.fastandroid.exception.ApiException;
5 | import com.hunter.fastandroid.vo.JsonResponse;
6 |
7 | import io.reactivex.functions.Function;
8 |
9 |
10 | /**
11 | * RxJava map转换
12 | *
13 | * @param
14 | * @author Hunter
15 | */
16 | public class JsonResponseFunc implements Function, T> {
17 | @Override
18 | public T apply(JsonResponse tJsonResponse) throws Exception {
19 | if (tJsonResponse == null) return null;
20 |
21 | if (!tJsonResponse.isSuccess()) {
22 | throw new ApiException(tJsonResponse);
23 | }
24 |
25 | return tJsonResponse.getData();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/rx/JsonResponseObserver.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.rx;
2 |
3 |
4 | import com.hunter.fastandroid.base.IBaseView;
5 | import com.hunter.fastandroid.exception.ApiException;
6 | import com.hunter.fastandroid.vo.JsonResponse;
7 |
8 | public abstract class JsonResponseObserver extends ResponseObserver {
9 | public JsonResponseObserver(IBaseView baseView) {
10 | super(baseView);
11 | }
12 |
13 | @Override
14 | public void onNext(T t) {
15 | if (t instanceof JsonResponse) {
16 | JsonResponse response = (JsonResponse) t;
17 | if (!response.isSuccess()) {
18 | onError(new ApiException(response));
19 | }else{
20 | onSuccess(t);
21 | }
22 | }
23 | }
24 |
25 | public abstract void onSuccess(T t);
26 | }
27 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/rx/ResponseObserver.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.rx;
2 |
3 | import com.hunter.fastandroid.R;
4 | import com.hunter.fastandroid.base.IBaseView;
5 | import com.hunter.fastandroid.exception.ApiException;
6 | import com.hunter.fastandroid.vo.JsonResponse;
7 |
8 | import io.reactivex.Observer;
9 | import io.reactivex.disposables.Disposable;
10 |
11 | /**
12 | * RxJava 自定义Subscriber
13 | *
14 | * @param
15 | * @author Hunter
16 | */
17 | public abstract class ResponseObserver implements Observer {
18 | private static final String TAG = "ResponseObserver";
19 | private IBaseView mBaseView;
20 | private Disposable disposable;
21 |
22 | public ResponseObserver(IBaseView baseView) {
23 | mBaseView = baseView;
24 | }
25 |
26 | @Override
27 | public void onSubscribe(Disposable disposable) {
28 | this.disposable = disposable;
29 | mBaseView.showProgress(R.string.loading);
30 | }
31 |
32 | @Override
33 | public void onError(Throwable e) {
34 | mBaseView.hideProgress();
35 | mBaseView.showToast(e.getMessage());
36 |
37 | if (e instanceof ApiException) {
38 | ApiException apiException = (ApiException) e;
39 |
40 | JsonResponse jsonResponse = apiException.getJsonResponse();
41 |
42 | if(jsonResponse.isTokenValid()){
43 | mBaseView.showToast(R.string.user_valid);
44 | mBaseView.clearUser();
45 | }else{
46 | mBaseView.showToast(jsonResponse.getMessage());
47 | }
48 | }else{
49 | mBaseView.showToast(R.string.system_error);
50 | }
51 | }
52 |
53 | @Override
54 | public void onComplete() {
55 | mBaseView.hideProgress();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/rx/ResponseSubscriber.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.rx;
2 |
3 | import android.content.DialogInterface;
4 |
5 | import com.hunter.fastandroid.base.IBaseView;
6 | import com.orhanobut.logger.Logger;
7 |
8 | import org.reactivestreams.Subscriber;
9 | import org.reactivestreams.Subscription;
10 |
11 | /**
12 | * RxJava 自定义Subscriber (使用背压时使用)
13 | *
14 | * @param
15 | * @author Hunter
16 | */
17 | public abstract class ResponseSubscriber implements Subscriber {
18 | private static final String TAG = "ResponseObserver";
19 | private IBaseView mBaseView;
20 | private Subscription subscription;
21 |
22 | public ResponseSubscriber(IBaseView baseView) {
23 | mBaseView = baseView;
24 | mBaseView.setProgressCancelListener(new DialogInterface.OnCancelListener() {
25 | @Override
26 | public void onCancel(DialogInterface dialog) {
27 | if(subscription != null){
28 | subscription.cancel();
29 | }
30 | }
31 | });
32 | }
33 |
34 | @Override
35 | public void onSubscribe(Subscription subscription) {
36 | this.subscription = subscription;
37 | mBaseView.showProgress("");
38 | }
39 |
40 | @Override
41 | public void onError(Throwable e) {
42 | mBaseView.hideProgress();
43 | if(null != e){
44 | mBaseView.showToast(e.getMessage());
45 | Logger.e(e.getMessage());
46 | }
47 | }
48 |
49 | @Override
50 | public void onComplete() {
51 | mBaseView.hideProgress();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/service/TestService.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.service;
2 |
3 | import com.hunter.fastandroid.app.URLs;
4 | import com.hunter.fastandroid.vo.DoubanResponse;
5 | import com.hunter.fastandroid.vo.JsonResponse;
6 |
7 | import io.reactivex.Flowable;
8 | import io.reactivex.Observable;
9 | import retrofit2.http.GET;
10 | import retrofit2.http.POST;
11 | import retrofit2.http.Query;
12 |
13 | /**
14 | * Created by Administrator on 2017/1/4.
15 | */
16 | public interface TestService {
17 | @GET(URLs.MODUEL_BOOK + URLs.SEARCH)
18 | Observable test(@Query("q") String keyword);
19 | }
20 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/activity/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.activity;
2 |
3 | import com.hunter.fastandroid.base.BaseActivity;
4 |
5 | public abstract class LoginActivity extends BaseActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/activity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.activity;
2 |
3 | import android.support.v7.widget.LinearLayoutManager;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.text.TextUtils;
6 | import android.view.View;
7 | import android.widget.Button;
8 | import android.widget.EditText;
9 |
10 | import com.hunter.fastandroid.R;
11 | import com.hunter.fastandroid.base.BaseActivity;
12 | import com.hunter.fastandroid.presenter.TestPresenter;
13 | import com.hunter.fastandroid.ui.adapter.BookAdapter;
14 | import com.hunter.fastandroid.ui.interfaces.ITestView;
15 | import com.hunter.fastandroid.ui.widget.TitleBar;
16 | import com.hunter.fastandroid.vo.Book;
17 |
18 | import java.util.List;
19 |
20 | import butterknife.BindView;
21 |
22 | public class MainActivity extends BaseActivity implements ITestView {
23 | @BindView(R.id.title_bar)
24 | TitleBar titleBar;
25 | @BindView(R.id.et_input)
26 | EditText etInput;
27 | @BindView(R.id.btn_search)
28 | Button btnSearch;
29 | @BindView(R.id.rv_book)
30 | RecyclerView rvBook;
31 |
32 | private BookAdapter bookAdapter;
33 |
34 | TestPresenter testPresenter;
35 |
36 | @Override
37 | protected int getContentResId() {
38 | return R.layout.activity_main;
39 | }
40 |
41 | @Override
42 | public void initView() {
43 | titleBar.setTitle("测试页面");
44 |
45 | bookAdapter = new BookAdapter(this);
46 | rvBook.setLayoutManager(new LinearLayoutManager(this));
47 | rvBook.setAdapter(bookAdapter);
48 |
49 | btnSearch.setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View view) {
52 | String keyword = etInput.getText().toString();
53 | if(TextUtils.isEmpty(keyword)){
54 | showToast("请先输入书名关键字");
55 | }else{
56 | searchBook(keyword);
57 | }
58 | }
59 | });
60 | }
61 |
62 | private void searchBook(String keyword) {
63 | testPresenter.test(keyword,this);
64 | }
65 |
66 | @Override
67 | public void initPresenter() {
68 | testPresenter = new TestPresenter();
69 | }
70 |
71 | @Override
72 | public void showData(List datas) {
73 | bookAdapter.setData(datas);
74 | bookAdapter.notifyDataSetChanged();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/adapter/BookAdapter.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.adapter;
2 |
3 | import android.content.Context;
4 | import android.widget.ImageView;
5 | import android.widget.TextView;
6 |
7 | import com.hunter.fastandroid.R;
8 | import com.hunter.fastandroid.base.BaseRecyclerAdapter;
9 | import com.hunter.fastandroid.base.RecyclerViewHolder;
10 | import com.hunter.fastandroid.utils.ImageLoadUtils;
11 | import com.hunter.fastandroid.vo.Book;
12 |
13 | public class BookAdapter extends BaseRecyclerAdapter {
14 |
15 | public BookAdapter(Context context) {
16 | super(context);
17 | }
18 |
19 | @Override
20 | public void bindView(RecyclerViewHolder holder, int position) {
21 | TextView tvName = holder.getView(R.id.tv_name);
22 | TextView tvPub = holder.getView(R.id.tv_publisher);
23 | TextView tvPrice = holder.getView(R.id.tv_price);
24 | ImageView ivImage = holder.getView(R.id.iv_image);
25 |
26 | tvName.setText(getItemData(position).getTitle());
27 | tvPub.setText(getItemData(position).getPublisher());
28 | tvPrice.setText(getItemData(position).getPrice());
29 | ImageLoadUtils.loadImage(getContext(), getItemData(position).getImage(), ivImage);
30 | }
31 |
32 | @Override
33 | public int getLayoutId() {
34 | return R.layout.item_book;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/interfaces/ITestView.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.interfaces;
2 |
3 | import com.hunter.fastandroid.base.IBaseView;
4 | import com.hunter.fastandroid.vo.Book;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Created by Administrator on 2017/1/4.
10 | */
11 | public interface ITestView extends IBaseView {
12 | void showData(List datas);
13 | }
14 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/widget/CountDownButton.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.widget;
2 |
3 | import android.content.Context;
4 | import android.os.CountDownTimer;
5 | import android.support.v7.widget.AppCompatTextView;
6 | import android.util.AttributeSet;
7 |
8 | import com.hunter.fastandroid.R;
9 |
10 |
11 | /**
12 | * Created by Administrator on 2017/5/5.
13 | */
14 |
15 | public class CountDownButton extends AppCompatTextView {
16 | private String oldText = "";
17 | static final int MAX_COUNT_DOWN = 60000;
18 | static final int COUNT_DOWN_INTERVAL = 1000;
19 |
20 | private CountDownTimer countDownTimer;
21 |
22 | public CountDownButton(Context context) {
23 | super(context);
24 | }
25 |
26 | public CountDownButton(Context context, AttributeSet attrs) {
27 | super(context, attrs);
28 | }
29 |
30 | public CountDownButton(Context context, AttributeSet attrs, int defStyleAttr) {
31 | super(context, attrs, defStyleAttr);
32 | }
33 |
34 | /**
35 | * 开始进行倒计时
36 | */
37 | public void startCountDown(){
38 | oldText = getText().toString();
39 | setEnabled(false);
40 | countDownTimer = new CountDownTimer(MAX_COUNT_DOWN, COUNT_DOWN_INTERVAL){
41 |
42 | @Override
43 | public void onTick(long millisUntilFinished) {
44 | setText(getContext().getString(R.string.countdown, millisUntilFinished / COUNT_DOWN_INTERVAL));
45 | }
46 |
47 | @Override
48 | public void onFinish() {
49 | setText(oldText);
50 | setEnabled(true);
51 | }
52 | }.start();
53 | }
54 |
55 | /**
56 | * 停止倒计时
57 | */
58 | public void stopCountDown(){
59 | countDownTimer.cancel();
60 | countDownTimer.onFinish();
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/widget/CustomGridView.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.GridView;
6 |
7 | /**
8 | * 不带滚动条自适应高度的GridView
9 | *
10 | * @author Hunter
11 | */
12 | public class CustomGridView extends GridView {
13 | public CustomGridView(Context context) {
14 | super(context);
15 | }
16 |
17 | public CustomGridView(Context context, AttributeSet attrs) {
18 | super(context, attrs);
19 | }
20 |
21 | public CustomGridView(Context context, AttributeSet attrs, int defStyleAttr) {
22 | super(context, attrs, defStyleAttr);
23 | }
24 |
25 | @Override
26 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
27 | int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
28 | MeasureSpec.AT_MOST);
29 | super.onMeasure(widthMeasureSpec, expandSpec);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/widget/CustomListView.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ListView;
6 |
7 | /**
8 | * 不带滚动条自适应高度的ListView
9 | *
10 | * @author Hunter
11 | */
12 | public class CustomListView extends ListView {
13 | public CustomListView(Context context) {
14 | super(context);
15 | }
16 |
17 | public CustomListView(Context context, AttributeSet attrs) {
18 | super(context, attrs);
19 | }
20 |
21 | public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
22 | super(context, attrs, defStyleAttr);
23 | }
24 |
25 | @Override
26 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
27 | int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
28 | MeasureSpec.AT_MOST);
29 | super.onMeasure(widthMeasureSpec, expandSpec);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/widget/CustomProgress.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.widget;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.view.WindowManager;
7 | import android.widget.TextView;
8 |
9 | import com.hunter.fastandroid.R;
10 | import com.wang.avi.AVLoadingIndicatorView;
11 |
12 |
13 | /**
14 | * Created by Administrator on 2017/5/25.
15 | */
16 |
17 | public class CustomProgress extends ProgressDialog {
18 | private AVLoadingIndicatorView loading;
19 | private TextView tvMessage;
20 | private CharSequence mMessage;
21 |
22 | public CustomProgress(Context context) {
23 | super(context);
24 | }
25 |
26 | public CustomProgress(Context context, int theme) {
27 | super(context, theme);
28 | }
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | init(getContext());
34 | }
35 |
36 | private void init(Context context) {
37 | setContentView(R.layout.progress);
38 |
39 | tvMessage = (TextView) findViewById(R.id.tv_message);
40 | if(mMessage != null){
41 | tvMessage.setText(mMessage);
42 | }
43 |
44 | loading = (AVLoadingIndicatorView) findViewById(R.id.avi);
45 | loading.smoothToShow();
46 |
47 | WindowManager.LayoutParams params = getWindow().getAttributes();
48 | params.width = WindowManager.LayoutParams.WRAP_CONTENT;
49 | params.height = WindowManager.LayoutParams.WRAP_CONTENT;
50 | getWindow().setAttributes(params);
51 | }
52 |
53 | @Override
54 | public void setMessage(CharSequence message) {
55 | if(tvMessage != null){
56 | tvMessage.setText(message);
57 | }else{
58 | mMessage = message;
59 | }
60 | }
61 |
62 | @Override
63 | public void show() {
64 | super.show();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/widget/NoZoomControllWebView.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.widget;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 | import android.webkit.WebView;
8 | import android.widget.ZoomButtonsController;
9 |
10 | /**
11 | * 不可缩放的WebView
12 | *
13 | * @author Hunter
14 | */
15 | public class NoZoomControllWebView extends WebView {
16 |
17 | private ZoomButtonsController mZoomButtonsController = null;
18 |
19 | public NoZoomControllWebView(Context context) {
20 | super(context);
21 | disableControls();
22 | }
23 |
24 | public NoZoomControllWebView(Context context, AttributeSet attrs, int defStyle) {
25 | super(context, attrs, defStyle);
26 | disableControls();
27 | }
28 |
29 | public NoZoomControllWebView(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | disableControls();
32 | }
33 |
34 | /**
35 | * Disable the controls
36 | */
37 | @SuppressLint("NewApi")
38 | private void disableControls() {
39 | this.getSettings().setBuiltInZoomControls(true);
40 | this.getSettings().setDisplayZoomControls(false);
41 | }
42 |
43 | @Override
44 | public boolean onTouchEvent(MotionEvent ev) {
45 | super.onTouchEvent(ev);
46 | if (mZoomButtonsController != null) {
47 | // Hide the controlls AFTER they where made visible by the default implementation.
48 | mZoomButtonsController.setVisible(false);
49 | }
50 | return true;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/ui/widget/TitleBar.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.ui.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.widget.ImageButton;
8 | import android.widget.LinearLayout;
9 | import android.widget.TextView;
10 |
11 | import com.hunter.fastandroid.R;
12 |
13 | /**
14 | * 自定义标题栏
15 | *
16 | * @author Hunter
17 | */
18 | public class TitleBar extends LinearLayout {
19 | private LayoutInflater mInflater;
20 | private View mHeader;
21 | private LinearLayout mLayoutLeftContainer;
22 | private LinearLayout mLayoutRightContainer;
23 | private LinearLayout mLayoutCenterContainer;
24 | private LinearLayout mHeaderTitle;
25 | private TextView mTvTitle;
26 | private ImageButton mLeftImageButton;
27 | private ImageButton mRightImageButton;
28 |
29 | public TitleBar(Context context) {
30 | super(context);
31 | init(context);
32 | }
33 |
34 | public TitleBar(Context context, AttributeSet attrs) {
35 | super(context, attrs);
36 | init(context);
37 | }
38 |
39 | private void init(Context context) {
40 | mInflater = LayoutInflater.from(context);
41 | mHeader = mInflater.inflate(R.layout.common_header, null);
42 | addView(mHeader);
43 | initViews();
44 | }
45 |
46 | /**
47 | * 初始化布局
48 | */
49 | private void initViews() {
50 | mLayoutLeftContainer = (LinearLayout) findViewByHeaderId(R.id.header_layout_leftview_container);
51 | mLayoutRightContainer = (LinearLayout) findViewByHeaderId(R.id.header_layout_rightview_container);
52 |
53 | mHeaderTitle = (LinearLayout) findViewByHeaderId(R.id.header_title);
54 | mTvTitle = (TextView) findViewByHeaderId(R.id.header_htv_subtitle);
55 |
56 | mLayoutCenterContainer = (LinearLayout) findViewByHeaderId(R.id.header_layout_middleview_container);
57 |
58 | initLeftView();
59 | initRightView();
60 |
61 | mLayoutLeftContainer.setVisibility(View.INVISIBLE);
62 | mLayoutRightContainer.setVisibility(View.INVISIBLE);
63 |
64 | mHeaderTitle.setVisibility(View.VISIBLE);
65 | mTvTitle.setVisibility(View.VISIBLE);
66 |
67 | mLayoutCenterContainer.setVisibility(View.GONE);
68 | }
69 |
70 | /**
71 | * 初始化左侧按钮
72 | */
73 | private void initLeftView() {
74 | View mleftImageButtonView = mInflater.inflate(
75 | R.layout.common_header_leftbutton, null);
76 | mLayoutLeftContainer.addView(mleftImageButtonView);
77 | mLeftImageButton = (ImageButton) mleftImageButtonView
78 | .findViewById(R.id.ib_titlebar_left);
79 | }
80 |
81 | /**
82 | * 初始化右侧按钮
83 | */
84 | private void initRightView() {
85 | View mRightImageButtonView = mInflater.inflate(
86 | R.layout.common_header_rightbutton, null);
87 | mLayoutRightContainer.addView(mRightImageButtonView);
88 | mRightImageButton = (ImageButton) mRightImageButtonView
89 | .findViewById(R.id.ib_titlebar_right);
90 | }
91 |
92 | /**
93 | * 在TitleBar中查找指定控件
94 | */
95 | public View findViewByHeaderId(int id) {
96 | return mHeader.findViewById(id);
97 | }
98 |
99 | /**
100 | * 设置TitleBar的标题
101 | */
102 | public void setTitle(CharSequence title) {
103 | mTvTitle.setText(title);
104 | mHeaderTitle.setVisibility(View.VISIBLE);
105 | mLayoutCenterContainer.setVisibility(View.GONE);
106 | }
107 |
108 | /**
109 | * 设置TitleBar的标题
110 | *
111 | * @param res
112 | */
113 | public void setTitle(int res) {
114 | mTvTitle.setText(res);
115 | mHeaderTitle.setVisibility(View.VISIBLE);
116 | mLayoutCenterContainer.setVisibility(View.GONE);
117 | }
118 |
119 | /**
120 | * 自定义左侧视图
121 | */
122 | public void setLeftView(View view) {
123 | mLayoutLeftContainer.removeAllViews();
124 | mLayoutLeftContainer.addView(view);
125 | mLayoutLeftContainer.setVisibility(View.VISIBLE);
126 | }
127 |
128 | /**
129 | * 自定义居中视图
130 | */
131 | public void setCenterView(View view) {
132 | mHeaderTitle.setVisibility(View.GONE);
133 | mLayoutCenterContainer.removeAllViews();
134 | mLayoutCenterContainer.addView(view);
135 | mLayoutCenterContainer.setVisibility(View.VISIBLE);
136 | }
137 |
138 | /**
139 | * 自定义右侧视图
140 | */
141 | public void setRightView(View view) {
142 | mLayoutRightContainer.removeAllViews();
143 | mLayoutRightContainer.addView(view);
144 | mLayoutRightContainer.setVisibility(View.VISIBLE);
145 | }
146 |
147 | /**
148 | * 设置文字标题以及左右的View
149 | *
150 | * @param title
151 | * @param leftView
152 | * @param rightView
153 | */
154 | public void setTitleBar(CharSequence title, View leftView, View rightView) {
155 | setTitle(title);
156 | setLeftView(leftView);
157 | setRightView(rightView);
158 | }
159 |
160 | /**
161 | * 设置文字标题以及左右的View
162 | *
163 | * @param title
164 | * @param leftView
165 | * @param rightView
166 | */
167 | public void setTitleBar(int title, View leftView, View rightView) {
168 | setTitle(title);
169 | setLeftView(leftView);
170 | setRightView(rightView);
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/utils/CommonUtils.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.pm.PackageInfo;
6 | import android.content.pm.PackageManager;
7 | import android.os.IBinder;
8 | import android.view.View;
9 | import android.view.inputmethod.InputMethodManager;
10 |
11 | import com.google.gson.Gson;
12 | import com.google.gson.GsonBuilder;
13 | import com.google.gson.JsonParseException;
14 | import com.google.gson.JsonParser;
15 | import com.hunter.fastandroid.app.BaseApplication;
16 |
17 | import java.security.MessageDigest;
18 | import java.util.Locale;
19 | import java.util.regex.Matcher;
20 | import java.util.regex.Pattern;
21 |
22 | /**
23 | * 通用工具类
24 | *
25 | * @author Hunter
26 | */
27 | public class CommonUtils {
28 | private static final String GSON_FORMAT = "yyyy-MM-dd HH:mm:ss";
29 | private static Gson mGson;
30 |
31 | /**
32 | * 验证json合法性
33 | *
34 | * @param jsonContent
35 | * @return
36 | */
37 | public static boolean isJsonFormat(String jsonContent) {
38 | try {
39 | new JsonParser().parse(jsonContent);
40 | return true;
41 | } catch (JsonParseException e) {
42 | return false;
43 | }
44 | }
45 |
46 |
47 | /**
48 | * 对指定字符串进行md5加密
49 | *
50 | * @param s
51 | * @return 加密后的数据
52 | */
53 | public static String EncryptMD5(String s) {
54 | char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
55 | 'a', 'b', 'c', 'd', 'e', 'f'};
56 | try {
57 | byte[] btInput = s.getBytes();
58 | // 获得MD5摘要算法的 MessageDigest 对象
59 | MessageDigest mdInst = MessageDigest.getInstance("MD5");
60 | // 使用指定的字节更新摘要
61 | mdInst.update(btInput);
62 | // 获得密文
63 | byte[] md = mdInst.digest();
64 | // 把密文转换成十六进制的字符串形式
65 | int j = md.length;
66 | char str[] = new char[j * 2];
67 | int k = 0;
68 | for (int i = 0; i < j; i++) {
69 | byte byte0 = md[i];
70 | str[k++] = hexDigits[byte0 >>> 4 & 0xf];
71 | str[k++] = hexDigits[byte0 & 0xf];
72 | }
73 | return new String(str);
74 | } catch (Exception e) {
75 | e.printStackTrace();
76 | return null;
77 | }
78 | }
79 |
80 | /**
81 | * 判断email格式是否正确
82 | *
83 | * @param email
84 | * @return
85 | */
86 | public static boolean isEmail(String email) {
87 | String str = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
88 | Pattern p = Pattern.compile(str);
89 | Matcher m = p.matcher(email);
90 | return m.matches();
91 | }
92 |
93 | /**
94 | * 根据系统语言判断是否为中国
95 | *
96 | * @return
97 | */
98 | public static boolean isZh() {
99 | Locale locale = BaseApplication.getInstance().getResources().getConfiguration().locale;
100 | String language = locale.getLanguage();
101 | if (language.startsWith("zh")) {
102 | return true;
103 | } else {
104 | return false;
105 | }
106 | }
107 |
108 | /**
109 | * 获取gson对象
110 | *
111 | * @return
112 | */
113 | public static Gson getGson() {
114 | if (mGson == null) {
115 | mGson = new GsonBuilder().setDateFormat(GSON_FORMAT).create(); // 创建gson对象,并设置日期格式
116 | }
117 |
118 | return mGson;
119 | }
120 |
121 | /**
122 | * 获取版本号
123 | *
124 | * @return 当前应用的版本号
125 | */
126 | public static String getVersion() {
127 | try {
128 | PackageManager manager = BaseApplication.getInstance().getPackageManager();
129 | PackageInfo info = manager.getPackageInfo(BaseApplication.getInstance().getPackageName(), 0);
130 | return info.versionName;
131 | } catch (Exception e) {
132 | e.printStackTrace();
133 | return "";
134 | }
135 | }
136 |
137 | /**
138 | * @param context
139 | */
140 | public static void hideSoftInput(Activity context) {
141 |
142 | try{
143 | InputMethodManager imm = (InputMethodManager) context
144 | .getSystemService(Context.INPUT_METHOD_SERVICE);
145 | IBinder ibinder = context.getCurrentFocus().getWindowToken();
146 | if((imm != null) && (ibinder != null)){
147 | imm.hideSoftInputFromWindow(ibinder, 0);
148 | }
149 | }catch (Exception e){
150 |
151 | }
152 | }
153 |
154 |
155 | public static void showSoftInput(Context context, View v) {
156 | InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
157 | if (!imm.isActive()) {
158 | imm.showSoftInput(v, 0);
159 | }
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/utils/DateUtils.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.utils;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 | import java.util.Locale;
8 |
9 | /**
10 | * 日期工具类
11 | *
12 | * @author Hunter
13 | */
14 | public class DateUtils {
15 |
16 | public static SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
17 | public static SimpleDateFormat formatDay = new SimpleDateFormat("d", Locale.getDefault());
18 | public static SimpleDateFormat formatMonthDay = new SimpleDateFormat("M-d", Locale.getDefault());
19 | public static SimpleDateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
20 |
21 | /**
22 | * 格式化日期
23 | *
24 | * @param date
25 | * @return 年月日
26 | */
27 | public static String formatDate(Date date) {
28 | return formatDate.format(date);
29 | }
30 |
31 | /**
32 | * 格式化日期
33 | *
34 | * @param date
35 | * @return 年月日 时分秒
36 | */
37 | public static String formatDateTime(Date date) {
38 | return formatDateTime.format(date);
39 | }
40 |
41 | /**
42 | * 将时间戳解析成日期
43 | *
44 | * @param timeInMillis
45 | * @return 年月日
46 | */
47 | public static String parseDate(long timeInMillis) {
48 | Calendar calendar = Calendar.getInstance();
49 | calendar.setTimeInMillis(timeInMillis);
50 | Date date = calendar.getTime();
51 | return formatDate(date);
52 | }
53 |
54 | /**
55 | * 将时间戳解析成日期
56 | *
57 | * @param timeInMillis
58 | * @return 年月日 时分秒
59 | */
60 | public static String parseDateTime(long timeInMillis) {
61 | Calendar calendar = Calendar.getInstance();
62 | calendar.setTimeInMillis(timeInMillis);
63 | Date date = calendar.getTime();
64 | return formatDateTime(date);
65 | }
66 |
67 | /**
68 | * 解析日期
69 | *
70 | * @param date
71 | * @return
72 | */
73 | public static Date parseDate(String date) {
74 | Date mDate = null;
75 | try {
76 | mDate = formatDate.parse(date);
77 | } catch (ParseException e) {
78 | e.printStackTrace();
79 | }
80 |
81 | return mDate;
82 | }
83 |
84 | /**
85 | * 解析日期
86 | *
87 | * @param datetime
88 | * @return
89 | */
90 | public static Date parseDateTime(String datetime) {
91 | Date mDate = null;
92 | try {
93 | mDate = formatDateTime.parse(datetime);
94 | } catch (ParseException e) {
95 | e.printStackTrace();
96 | }
97 |
98 | return mDate;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/utils/DialogUtils.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.utils;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 |
7 | import com.hunter.fastandroid.R;
8 |
9 |
10 | /**
11 | * Created by Administrator on 2017/6/8.
12 | */
13 |
14 | public class DialogUtils {
15 | public static void showConfirmDialog(Context context, String message, DialogInterface.OnClickListener onClickListener) {
16 | showConfirmDialog(context, message, true, onClickListener);
17 | }
18 |
19 | public static void showConfirmDialog(Context context, int messageRes, DialogInterface.OnClickListener onClickListener) {
20 | showConfirmDialog(context, context.getString(messageRes), onClickListener);
21 | }
22 |
23 | /**
24 | * 显示一个确认对话框
25 | * @param context
26 | * @param message
27 | * @param onClickListener
28 | */
29 | public static void showConfirmDialog(Context context, String message, boolean cancelable, DialogInterface.OnClickListener onClickListener) {
30 | new AlertDialog
31 | .Builder(context)
32 | .setMessage(message)
33 | .setCancelable(cancelable)
34 | .setPositiveButton(R.string.confirm, onClickListener)
35 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
36 | @Override
37 | public void onClick(DialogInterface dialog, int which) {
38 | dialog.dismiss();
39 | }
40 | })
41 | .show();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/utils/FileInfoUtils.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.text.DecimalFormat;
6 |
7 | /**
8 | * 文件或文件夹操作工具类
9 | *
10 | * @author Hunter
11 | */
12 | public class FileInfoUtils {
13 | /**
14 | * 返回自定文件或文件夹的大小
15 | *
16 | * @param f
17 | * @return
18 | * @throws Exception
19 | */
20 | public static long getFileSizes(File f) throws Exception {// 取得文件大小
21 | long s = 0;
22 | if (f.exists()) {
23 | FileInputStream fis = new FileInputStream(f);
24 | s = fis.available();
25 | fis.close();
26 | } else {
27 | f.createNewFile();
28 | System.out.println("文件不存在");
29 | }
30 | return s;
31 | }
32 |
33 | // 递归
34 | public static long getFileSize(File f) throws Exception// 取得文件夹大小
35 | {
36 | long size = 0;
37 | File flist[] = f.listFiles();
38 | for (int i = 0; i < flist.length; i++) {
39 | if (flist[i].isDirectory()) {
40 | size = size + getFileSize(flist[i]);
41 | } else {
42 | size = size + flist[i].length();
43 | }
44 | }
45 | return size;
46 | }
47 |
48 | public static String FormetFileSize(long fileS) {// 转换文件大小
49 | DecimalFormat df = new DecimalFormat("#0.00");
50 | String fileSizeString = "";
51 | if (fileS < 1024) {
52 | fileSizeString = df.format((double) fileS) + "B";
53 | } else if (fileS < 1048576) {
54 | fileSizeString = df.format((double) fileS / 1024) + "K";
55 | } else if (fileS < 1073741824) {
56 | fileSizeString = df.format((double) fileS / 1048576) + "M";
57 | } else {
58 | fileSizeString = df.format((double) fileS / 1073741824) + "G";
59 | }
60 | return fileSizeString;
61 | }
62 |
63 | public static long getlist(File f) {// 递归求取目录文件个数
64 | long size = 0;
65 | File flist[] = f.listFiles();
66 | size = flist.length;
67 | for (int i = 0; i < flist.length; i++) {
68 | if (flist[i].isDirectory()) {
69 | size = size + getlist(flist[i]);
70 | size--;
71 | }
72 | }
73 | return size;
74 |
75 | }
76 | }
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/utils/ImageLoadUtils.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.utils;
2 |
3 | import android.content.Context;
4 | import android.widget.ImageView;
5 |
6 | import com.bumptech.glide.Glide;
7 | import com.bumptech.glide.request.RequestOptions;
8 | import com.hunter.fastandroid.R;
9 |
10 | /**
11 | * 图片加载工具类
12 | * 为方便以后随时更换图片加载库
13 | * 并且统一配置图片加载方式
14 | *
15 | * @author Hunter
16 | */
17 | public class ImageLoadUtils {
18 |
19 | public static final int DEFAULT_PLACEHOLDER_RESID = R.mipmap.ic_launcher;
20 |
21 | public static void loadImage(Context context, String imageUrl, int resId, ImageView imageView) {
22 | RequestOptions options = new RequestOptions()
23 | .placeholder(resId);
24 |
25 | Glide
26 | .with(context)
27 | .load(imageUrl)
28 | .apply(options)
29 | .into(imageView);
30 | }
31 |
32 | public static void loadImage(Context context, String imageUrl, ImageView imageView) {
33 | loadImage(context, imageUrl, DEFAULT_PLACEHOLDER_RESID, imageView);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/fastandroid/src/main/java/com/hunter/fastandroid/utils/MyStringUtils.java:
--------------------------------------------------------------------------------
1 | package com.hunter.fastandroid.utils;
2 |
3 | import android.util.Log;
4 |
5 | import java.security.MessageDigest;
6 | import java.security.NoSuchAlgorithmException;
7 | import java.text.ParseException;
8 | import java.text.SimpleDateFormat;
9 | import java.util.ArrayList;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import java.util.regex.Matcher;
13 | import java.util.regex.Pattern;
14 |
15 | /**
16 | * 字符串操作工具类
17 | *
18 | * @author Hunter
19 | */
20 | public class MyStringUtils {
21 | private final static Pattern EMAILER = Pattern
22 | .compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
23 | private final static ThreadLocal DATE_FORMATER = new ThreadLocal() {
24 | @Override
25 | protected SimpleDateFormat initialValue() {
26 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
27 | }
28 | };
29 | private static final String _BR = "
";
30 | private final static ThreadLocal dateFormater2 = new ThreadLocal() {
31 | @Override
32 | protected SimpleDateFormat initialValue() {
33 | return new SimpleDateFormat("yyyy-MM-dd");
34 | }
35 | };
36 |
37 | /**
38 | * 字符串截取
39 | *
40 | * @param str
41 | * @param length
42 | * @return
43 | * @throws Exception
44 | */
45 | public static String subString(String str, int length) throws Exception {
46 |
47 | byte[] bytes = str.getBytes("Unicode");
48 | int n = 0; // 表示当前的字节数
49 | int i = 2; // 要截取的字节数,从第3个字节开始
50 | for (; i < bytes.length && n < length; i++) {
51 | // 奇数位置,如3、5、7等,为UCS2编码中两个字节的第二个字节
52 | if (i % 2 == 1) {
53 | n++; // 在UCS2第二个字节时n加1
54 | } else {
55 | // 当UCS2编码的第一个字节不等于0时,该UCS2字符为汉字,一个汉字算两个字节
56 | if (bytes[i] != 0) {
57 | n++;
58 | }
59 | }
60 | }
61 | // 如果i为奇数时,处理成偶数
62 | if (i % 2 == 1) {
63 | // 该UCS2字符是汉字时,去掉这个截一半的汉字
64 | if (bytes[i - 1] != 0)
65 | i = i - 1;
66 | // 该UCS2字符是字母或数字,则保留该字符
67 | else
68 | i = i + 1;
69 | }
70 | return new String(bytes, 0, i, "Unicode");
71 | }
72 |
73 | /**
74 | * @param input
75 | * @return
76 | */
77 | public static String toDBC(String input) {
78 | char[] c = input.toCharArray();
79 | for (int i = 0; i < c.length; i++) {
80 | if (c[i] == 12288) {
81 | c[i] = (char) 32;
82 | continue;
83 | }
84 | if (c[i] > 65280 && c[i] < 65375)
85 | c[i] = (char) (c[i] - 65248);
86 | }
87 | return new String(c);
88 | }
89 |
90 | /**
91 | * 计算微博内容的长度 1个汉字 == 两个英文字母所占的长度 标点符号区分英文和中文
92 | *
93 | * @param c 所要统计的字符序列
94 | * @return 返回字符序列计算的长度
95 | */
96 | public static long calculateWeiboLength(CharSequence c) {
97 |
98 | double len = 0;
99 | for (int i = 0; i < c.length(); i++) {
100 | int temp = (int) c.charAt(i);
101 | if (temp > 0 && temp < 127) {
102 | len += 0.5;
103 | } else {
104 | len++;
105 | }
106 | }
107 | return Math.round(len);
108 | }
109 |
110 | /**
111 | * 分割字符串
112 | *
113 | * @param str String 原始字符串
114 | * @param splitsign String 分隔符
115 | * @return String[] 分割后的字符串数组
116 | */
117 | public static String[] split(String str, String splitsign) {
118 | int index;
119 | if (str == null || splitsign == null)
120 | return null;
121 | ArrayList al = new ArrayList();
122 | while ((index = str.indexOf(splitsign)) != -1) {
123 | al.add(str.substring(0, index));
124 | str = str.substring(index + splitsign.length());
125 | }
126 | al.add(str);
127 | return (String[]) al.toArray(new String[0]);
128 | }
129 |
130 | /**
131 | * 替换字符串
132 | *
133 | * @param from String 原始字符串
134 | * @param to String 目标字符串
135 | * @param source String 母字符串
136 | * @return String 替换后的字符串
137 | */
138 | public static String replace(String from, String to, String source) {
139 | if (source == null || from == null || to == null)
140 | return null;
141 | StringBuffer bf = new StringBuffer("");
142 | int index = -1;
143 | while ((index = source.indexOf(from)) != -1) {
144 | bf.append(source.substring(0, index) + to);
145 | source = source.substring(index + from.length());
146 | index = source.indexOf(from);
147 | }
148 | bf.append(source);
149 | return bf.toString();
150 | }
151 |
152 | /**
153 | * 替换字符串,能能够在HTML页面上直接显示(替换双引号和小于号)
154 | *
155 | * @param str String 原始字符串
156 | * @return String 替换后的字符串
157 | */
158 | public static String htmlencode(String str) {
159 | if (str == null) {
160 | return null;
161 | }
162 |
163 | return replace("\"", """, replace("<", "<", str));
164 | }
165 |
166 | /**
167 | * 替换字符串,将被编码的转换成原始码(替换成双引号和小于号)
168 | *
169 | * @param str String
170 | * @return String
171 | */
172 | public static String htmldecode(String str) {
173 | if (str == null) {
174 | return null;
175 | }
176 |
177 | return replace(""", "\"", replace("<", "<", str));
178 | }
179 |
180 | /**
181 | * 在页面上直接显示文本内容,替换小于号,空格,回车,TAB
182 | *
183 | * @param str String 原始字符串
184 | * @return String 替换后的字符串
185 | */
186 | public static String htmlshow(String str) {
187 | if (str == null) {
188 | return null;
189 | }
190 |
191 | str = replace("<", "<", str);
192 | str = replace(" ", " ", str);
193 | str = replace("\r\n", _BR, str);
194 | str = replace("\n", _BR, str);
195 | str = replace("\t", " ", str);
196 | return str;
197 | }
198 |
199 | /**
200 | * 返回指定字节长度的字符串
201 | *
202 | * @param str String 字符串
203 | * @param length int 指定长度
204 | * @return String 返回的字符串
205 | */
206 | public static String toLength(String str, int length) {
207 | if (str == null) {
208 | return null;
209 | }
210 | if (length <= 0) {
211 | return "";
212 | }
213 | try {
214 | if (str.getBytes("GBK").length <= length) {
215 | return str;
216 | }
217 | } catch (Exception ex) {
218 | }
219 | StringBuffer buff = new StringBuffer();
220 |
221 | int index = 0;
222 | char c;
223 | length -= 3;
224 | while (length > 0) {
225 | c = str.charAt(index);
226 | if (c < 128) {
227 | length--;
228 | } else {
229 | length--;
230 | length--;
231 | }
232 | buff.append(c);
233 | index++;
234 | }
235 | buff.append("...");
236 | return buff.toString();
237 | }
238 |
239 | /**
240 | * 获取url的后缀名
241 | *
242 | * @param urlString
243 | * @return
244 | */
245 | public static String getUrlFileName(String urlString) {
246 | String fileName = urlString.substring(urlString.lastIndexOf("/"));
247 | fileName = fileName.substring(1, fileName.length());
248 | if (fileName.equalsIgnoreCase("")) {
249 | Calendar c = Calendar.getInstance();
250 | fileName = c.get(Calendar.YEAR) + "" + c.get(Calendar.MONTH) + ""
251 | + c.get(Calendar.DAY_OF_MONTH) + ""
252 | + c.get(Calendar.MINUTE);
253 |
254 | }
255 | return fileName;
256 | }
257 |
258 | public static String replaceSomeString(String str) {
259 | String dest = "";
260 | try {
261 | if (str != null) {
262 | str = str.replaceAll("\r", "");
263 | str = str.replaceAll(">", ">");
264 | str = str.replaceAll("“", "“");
265 | str = str.replaceAll("”", "”");
266 | str = str.replaceAll("'", "'");
267 | str = str.replaceAll(" ", "");
268 | str = str.replaceAll("
", "\n");
269 | str = str.replaceAll(""", "\"");
270 | str = str.replaceAll("<", "<");
271 | str = str.replaceAll("‘", "《");
272 | str = str.replaceAll("’", "》");
273 | str = str.replaceAll("·", "·");
274 | str = str.replace("—", "—");
275 | str = str.replace("…", "…");
276 | str = str.replace("&", "×");
277 | str = str.replaceAll("\\s*", "");
278 | str = str.trim();
279 | str = str.replaceAll("", "\n ");
280 | str = str.replaceAll("
", "");
281 | str = str.replaceAll("", "\n ");
282 | str = str.replaceAll("", "");
283 | dest = str;
284 | }
285 | } catch (Exception e) {
286 | // TODO: handle exception
287 | }
288 |
289 | return dest;
290 | }
291 |
292 | /**
293 | * 清除文本里面的HTML标签
294 | *
295 | * @param htmlStr
296 | * @return
297 | */
298 | public static String delHTMLTag(String htmlStr) {
299 | String regEx_script = "