├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── dev
│ └── release
│ │ └── output.json
├── pro
│ └── release
│ │ └── output.json
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── allen
│ │ └── wanandroid
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── allen
│ │ │ └── wanandroid
│ │ │ ├── adapter
│ │ │ ├── CategoryHomeAdapter.java
│ │ │ ├── CategoryTagFlowAdapter.java
│ │ │ ├── CollectAdapter.java
│ │ │ ├── CommonFragmentAdapter.java
│ │ │ ├── CommonFragmentWithTitleAdapter.java
│ │ │ ├── HomeAdapter.java
│ │ │ ├── ProjectArticleAdapter.java
│ │ │ └── TagFlowAdapter.java
│ │ │ ├── api
│ │ │ ├── ApiModel.java
│ │ │ └── ApiService.java
│ │ │ ├── app
│ │ │ └── App.java
│ │ │ ├── arouter
│ │ │ ├── ARouterHelper.java
│ │ │ ├── ARouterPath.java
│ │ │ └── LoginInterceptor.java
│ │ │ ├── bean
│ │ │ ├── BannerBean.java
│ │ │ ├── CategoryBean.java
│ │ │ ├── CollectBean.java
│ │ │ ├── HomeBean.java
│ │ │ ├── HotBean.java
│ │ │ ├── MovieBean.java
│ │ │ └── UserBean.java
│ │ │ ├── broadcast
│ │ │ └── LoginBroadcastReceiver.java
│ │ │ ├── constant
│ │ │ └── BundleKey.java
│ │ │ ├── db
│ │ │ ├── DaoMaster.java
│ │ │ ├── DaoSession.java
│ │ │ ├── StringConverter.java
│ │ │ └── UserBeanDao.java
│ │ │ ├── ui
│ │ │ ├── MainActivity.java
│ │ │ ├── SplashActivity.java
│ │ │ ├── article
│ │ │ │ ├── ArticleFragment.java
│ │ │ │ ├── ArticlePresenter.java
│ │ │ │ ├── ArticleTabViewPagerActivity.java
│ │ │ │ └── ArticleView.java
│ │ │ ├── category
│ │ │ │ ├── CategoryHomeFragment.java
│ │ │ │ ├── CategoryHomePresenter.java
│ │ │ │ └── CategoryHomeView.java
│ │ │ ├── collect
│ │ │ │ ├── CollectPresenter.java
│ │ │ │ ├── CollectView.java
│ │ │ │ └── UserCollectActivity.java
│ │ │ ├── home
│ │ │ │ └── HomeFragment.java
│ │ │ ├── login
│ │ │ │ ├── LoginActivity.java
│ │ │ │ ├── LoginPresenter.java
│ │ │ │ └── LoginView.java
│ │ │ ├── mine
│ │ │ │ ├── AboutActivity.java
│ │ │ │ ├── MineHomeFragment.java
│ │ │ │ ├── MineHomePresenter.java
│ │ │ │ ├── MineHomeView.java
│ │ │ │ └── SettingActivity.java
│ │ │ ├── project
│ │ │ │ ├── ProjectArticleFragment.java
│ │ │ │ ├── ProjectArticlePresenter.java
│ │ │ │ ├── ProjectArticleView.java
│ │ │ │ ├── ProjectHomeFragment.java
│ │ │ │ ├── ProjectHomePresenter.java
│ │ │ │ └── ProjectHomeView.java
│ │ │ ├── search
│ │ │ │ ├── HotSearchFragment.java
│ │ │ │ ├── SearchActivity.java
│ │ │ │ ├── SearchPresenter.java
│ │ │ │ ├── SearchResultFragment.java
│ │ │ │ └── SearchViewView.java
│ │ │ └── webview
│ │ │ │ ├── WebViewActivity.java
│ │ │ │ ├── WebViewPresenter.java
│ │ │ │ └── WebViewView.java
│ │ │ ├── utils
│ │ │ ├── DbUtils.java
│ │ │ ├── DisplayUtils.java
│ │ │ └── GlideUtils.java
│ │ │ └── widget
│ │ │ └── CustomViewPager.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_search_close_white_24dp.xml
│ │ ├── ic_search_white_24dp.xml
│ │ ├── progress_web_view_bg.xml
│ │ ├── shape_category_tag_bg.xml
│ │ └── shape_tag_bg.xml
│ │ ├── layout
│ │ ├── activity_about.xml
│ │ ├── activity_article.xml
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_setting.xml
│ │ ├── activity_splash.xml
│ │ ├── activity_webview.xml
│ │ ├── adapter_item_category.xml
│ │ ├── adapter_item_category_tag.xml
│ │ ├── adapter_item_collect.xml
│ │ ├── adapter_item_header_banner.xml
│ │ ├── adapter_item_home.xml
│ │ ├── adapter_item_project_article.xml
│ │ ├── dialog_loading_layout.xml
│ │ ├── fragment_category_home.xml
│ │ ├── fragment_home.xml
│ │ ├── fragment_hot_search.xml
│ │ ├── fragment_mine.xml
│ │ ├── fragment_movie.xml
│ │ ├── fragment_project.xml
│ │ ├── fragment_search.xml
│ │ ├── item_tag.xml
│ │ ├── recycler_view.xml
│ │ └── recycler_view_empty_layout.xml
│ │ ├── menu
│ │ └── toolbar_search_menu.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── icon_arrow_b.png
│ │ └── icon_arrow_r.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── icon_arrow_more.png
│ │ ├── icon_category_selected.png
│ │ ├── icon_category_unselected.png
│ │ ├── icon_collected.png
│ │ ├── icon_head_img.png
│ │ ├── icon_home_selected.png
│ │ ├── icon_home_unselected.png
│ │ ├── icon_liked.png
│ │ ├── icon_mine_selected.png
│ │ ├── icon_mine_unselected.png
│ │ ├── icon_more.png
│ │ ├── icon_project_selected.png
│ │ ├── icon_project_unselected.png
│ │ ├── icon_splash.png
│ │ └── icon_uncollect.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── allen
│ └── wanandroid
│ └── ExampleUnitTest.java
├── build.gradle
├── config.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library_net
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── allen
│ │ └── library
│ │ ├── RxHttpUtils.java
│ │ ├── base
│ │ ├── BaseDataObserver.java
│ │ ├── BaseObserver.java
│ │ └── BaseStringObserver.java
│ │ ├── bean
│ │ └── BaseData.java
│ │ ├── config
│ │ └── OkHttpConfig.java
│ │ ├── constant
│ │ └── SPKeys.java
│ │ ├── cookie
│ │ ├── CookieJarImpl.java
│ │ ├── SerializableCookie.java
│ │ └── store
│ │ │ ├── CookieStore.java
│ │ │ ├── MemoryCookieStore.java
│ │ │ └── SPCookieStore.java
│ │ ├── download
│ │ ├── BaseDownloadObserver.java
│ │ ├── DownloadApi.java
│ │ ├── DownloadManager.java
│ │ ├── DownloadObserver.java
│ │ ├── DownloadRetrofit.java
│ │ └── ProgressListener.java
│ │ ├── exception
│ │ └── ApiException.java
│ │ ├── gson
│ │ ├── DoubleDefault0Adapter.java
│ │ ├── GsonAdapter.java
│ │ ├── IntegerDefault0Adapter.java
│ │ └── LongDefault0Adapter.java
│ │ ├── http
│ │ ├── GlobalRxHttp.java
│ │ ├── HttpClient.java
│ │ ├── RetrofitClient.java
│ │ ├── SSLUtils.java
│ │ └── SingleRxHttp.java
│ │ ├── interceptor
│ │ ├── AddCookiesInterceptor.java
│ │ ├── HeaderInterceptor.java
│ │ ├── NetCacheInterceptor.java
│ │ ├── NoNetCacheInterceptor.java
│ │ ├── ReceivedCookiesInterceptor.java
│ │ ├── RxHttpLogger.java
│ │ └── Transformer.java
│ │ ├── interfaces
│ │ ├── IDataSubscriber.java
│ │ ├── IStringSubscriber.java
│ │ └── ISubscriber.java
│ │ ├── manage
│ │ ├── IRxHttpManager.java
│ │ └── RxHttpManager.java
│ │ ├── observer
│ │ ├── CommonObserver.java
│ │ ├── DataObserver.java
│ │ └── StringObserver.java
│ │ ├── upload
│ │ ├── UploadFileApi.java
│ │ └── UploadRetrofit.java
│ │ └── utils
│ │ ├── AppUtils.java
│ │ ├── GsonUtils.java
│ │ ├── JsonUtil.java
│ │ ├── MD5.java
│ │ ├── NetUtils.java
│ │ ├── ParamUtils.java
│ │ ├── SPUtils.java
│ │ └── ToastUtils.java
│ └── res
│ └── values
│ └── strings.xml
├── module_base
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── library
│ │ └── base
│ │ ├── adapter
│ │ └── CommonFragmentAdapter.java
│ │ ├── base
│ │ ├── BaseActivity.java
│ │ ├── BaseFragment.java
│ │ ├── BaseMainActivity.java
│ │ ├── BaseToolBarTabViewPagerActivity.java
│ │ └── ErrorFragment.java
│ │ ├── bean
│ │ └── Tab.java
│ │ ├── mvp
│ │ ├── BaseMvpActivity.java
│ │ ├── BaseMvpFragment.java
│ │ ├── BaseMvpPresenter.java
│ │ ├── IBaseMvpPresenter.java
│ │ └── IBaseMvpView.java
│ │ ├── permission
│ │ ├── BasePermissionActivity.java
│ │ └── PermissionListener.java
│ │ ├── utils
│ │ ├── ActivityCollector.java
│ │ ├── DateUtils.java
│ │ ├── FormatUtils.java
│ │ ├── GetImagePath.java
│ │ ├── ImageUtils.java
│ │ ├── InstallUtil.java
│ │ ├── MathUtils.java
│ │ ├── PhoneFormatUtils.java
│ │ ├── SpannableStringUtils.java
│ │ ├── StatusBarUtil.java
│ │ ├── ToastUtils.java
│ │ └── VerifyUtils.java
│ │ ├── view
│ │ └── RVView.java
│ │ └── widget
│ │ ├── BottomTabView.java
│ │ ├── LoadingDialog.java
│ │ ├── SuperDividerItemDecoration.java
│ │ ├── TabView.java
│ │ └── TopBar.java
│ └── res
│ ├── color
│ └── selector_tab_text.xml
│ ├── drawable-v21
│ ├── item_touch_bg.xml
│ └── selector_topbar_back.xml
│ ├── drawable
│ ├── dialog_loading_animation_rotate.xml
│ ├── dialog_loading_bg.xml
│ ├── item_touch_bg.xml
│ ├── main_bottom_tob_background.xml
│ ├── selector_topbar_back.xml
│ ├── shape_bottom_tab_msg_bg.xml
│ ├── shape_search_bar_input_bg.xml
│ └── shape_super_toast.xml
│ ├── layout
│ ├── activity_base.xml
│ ├── activity_base_bottom_tab.xml
│ ├── activity_base_toolbar_tab_viewpager.xml
│ ├── base_custom_tab_item_layout.xml
│ ├── dialog_loading_layout.xml
│ ├── fragment_base.xml
│ ├── fragment_error.xml
│ ├── fragment_recyclerview.xml
│ ├── tab_indicator.xml
│ └── top_bar_layout.xml
│ ├── mipmap-xxhdpi
│ ├── app_back_icon_3x.png
│ └── img_progress_bar.png
│ └── values
│ ├── app_colors.xml
│ ├── attrs.xml
│ ├── colors.xml
│ ├── ids_topbar.xml
│ ├── strings.xml
│ └── styles.xml
├── settings.gradle
└── wan_android_keystore.jks
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .DS_Store
5 | /build
6 | /captures
7 | .externalNativeBuild
8 | ### Android template
9 | # Built application files
10 | *.apk
11 | *.ap_
12 |
13 | # Files for the ART/Dalvik VM
14 | *.dex
15 |
16 | # Java class files
17 | *.class
18 |
19 | # Generated files
20 | bin/
21 | gen/
22 | out/
23 |
24 | # Gradle files
25 | .gradle/
26 | build/
27 |
28 | # Local configuration file (sdk path, etc)
29 | local.properties
30 |
31 | # Proguard folder generated by Eclipse
32 | proguard/
33 |
34 | # Log Files
35 | *.log
36 |
37 | # Android Studio Navigation editor temp files
38 | .navigation/
39 |
40 | # Android Studio captures folder
41 | captures/
42 |
43 |
44 | .idea/
45 | # Keystore files
46 | # Uncomment the following line if you do not want to check your keystore files in.
47 | #*.jks
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WanAndroid
2 | # MVP+RxJava+Retrofit+Arouter的练手项目(为模块化开发做准备)
3 | > # 模块化代码请查看[module分支](https://github.com/lygttpod/WanAndroid/tree/module)
4 |
5 | * 1、为何写这个项目:
6 | > 写此项目的目的是为了加深对MVP架构的理解,并把自己封装的一套快速开发框架(base封装)应用于真实的项目中看看是否会出现未知问题,
7 | 同时尝试使用ARoute的方式对项目进行页面跳转管理,为以后模块化开发做准备。还可以把学到的新技术引入到此项目
8 | * 2、通过这个项目我们能学到什么:
9 | > a、用过这个练手项目我们能进一步熟悉MVP模式
10 | b、能够简单了解到ARouter的基本用法
11 | c、学习RxJava+Retrofit网路架构的封装
12 | d、学习基类的封装,如何满足大部分需求
13 | e、抛砖引玉,带你开发一套属于自己的快速开发架构
14 | f、反射的应用场景(简单通用的BaseMainActivity)
15 | g、待你自己去发现...
16 |
17 | * 3、接下来要怎么做
18 | > 有了以上基础,接下来就可以继续学习模块化开发了,项目后续会新建module分支用于练习模块化开发,带你一步一步去实现传说中的模块化/组件化demo
19 |
20 |
21 | ## 如有问题可以提issue或加群讨论
22 |
23 |
24 | 或者手动加QQ群:688433795
25 |
26 | ## Demo示例下载
27 | 
28 |
29 | # 项目接口
30 | [玩Android接口](http://www.wanandroid.com/blog/show/2)
31 |
32 | # 依赖库
33 | ### RxJava + Retrofit2 + Glide + ARouter
34 | * [RxJava2](https://github.com/ReactiveX/RxJava)
35 | * [Retrofit2](https://github.com/square/retrofit)
36 | * [ARouter](https://github.com/alibaba/ARouter)
37 | * [Flowlayout](https://github.com/hongyangAndroid/FlowLayout)
38 | * [BRVAH](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)
39 | * [Glide](https://github.com/bumptech/glide)
40 | * [RxHttpUtils](https://github.com/lygttpod/RxHttpUtils)
41 | * [SuperTextView](https://github.com/lygttpod/SuperTextView)
42 |
43 |
44 |
45 | # 运行效果
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/dev/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":100,"versionName":"1.0.0","enabled":true,"outputFile":"WanAndroid_v1.0.0_2018-08-06_dev.apk","fullName":"devRelease","baseName":"dev-release"},"path":"WanAndroid_v1.0.0_2018-08-06_dev.apk","properties":{}}]
--------------------------------------------------------------------------------
/app/pro/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":100,"versionName":"1.0.0","enabled":true,"outputFile":"WanAndroid_v1.0.0_2018-08-06_pro.apk","fullName":"proRelease","baseName":"pro-release"},"path":"WanAndroid_v1.0.0_2018-08-06_pro.apk","properties":{}}]
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/allen/wanandroid/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.allen.wanandroid;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.allen.quickbuildandroid", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/allen/wanandroid/adapter/CategoryHomeAdapter.java:
--------------------------------------------------------------------------------
1 | package com.allen.wanandroid.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.Nullable;
5 | import android.util.SparseArray;
6 | import android.view.View;
7 |
8 | import com.allen.wanandroid.R;
9 | import com.allen.wanandroid.bean.CategoryBean;
10 | import com.chad.library.adapter.base.BaseQuickAdapter;
11 | import com.chad.library.adapter.base.BaseViewHolder;
12 | import com.zhy.view.flowlayout.FlowLayout;
13 | import com.zhy.view.flowlayout.TagFlowLayout;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | *
19 | * @author : xiaoyao 20 | * e-mail : xiaoyao@51vest.com 21 | * date : 2018/07/24 22 | * desc : 23 | * version : 1.0 24 | *25 | */ 26 | public class CategoryHomeAdapter extends BaseQuickAdapter
17 | * @author : xiaoyao 18 | * e-mail : xiaoyao@51vest.com 19 | * date : 2018/07/27 20 | * desc : 21 | * version : 1.0 22 | *23 | */ 24 | public class CategoryTagFlowAdapter extends TagAdapter
15 | * @author : Allen 16 | * e-mail : lygttpod@163.com 17 | * date : 2018/07/21 18 | * desc : 19 | * version : 1.0 20 | *21 | */ 22 | public class CollectAdapter extends BaseQuickAdapter
12 | * @author : xiaoyao 13 | * e-mail : xiaoyao@51vest.com 14 | * date : 2018/07/27 15 | * desc : 16 | * version : 1.0 17 | *18 | */ 19 | public class CommonFragmentAdapter extends FragmentPagerAdapter { 20 | 21 | private List
13 | * @author : xiaoyao 14 | * e-mail : xiaoyao@51vest.com 15 | * date : 2018/07/27 16 | * desc : 17 | * version : 1.0 18 | *19 | */ 20 | public class CommonFragmentWithTitleAdapter extends FragmentPagerAdapter { 21 | 22 | private List
16 | * @author : Allen 17 | * e-mail : lygttpod@163.com 18 | * date : 2018/07/21 19 | * desc : 20 | * version : 1.0 21 | *22 | */ 23 | public class HomeAdapter extends BaseQuickAdapter
17 | * @author : Allen 18 | * e-mail : lygttpod@163.com 19 | * date : 2018/07/21 20 | * desc : 21 | * version : 1.0 22 | *23 | */ 24 | public class ProjectArticleAdapter extends BaseQuickAdapter
19 | * @author : xiaoyao 20 | * e-mail : xiaoyao@51vest.com 21 | * date : 2018/07/27 22 | * desc : 23 | * version : 1.0 24 | *25 | */ 26 | public class TagFlowAdapter extends TagAdapter
9 | * @author : xiaoyao 10 | * e-mail : xiaoyao@51vest.com 11 | * date : 2018/08/01 12 | * desc : 页面跳转 13 | * version : 1.0 14 | *15 | */ 16 | public class ARouterHelper { 17 | public static void gotoSearchActivity() { 18 | ARouter 19 | .getInstance() 20 | .build(ARouterPath.searchActPath) 21 | .navigation(); 22 | } 23 | 24 | public static void gotoWebViewActivity(String title, String url) { 25 | ARouter 26 | .getInstance() 27 | .build(ARouterPath.webViewPath) 28 | .withString(BundleKey.TITLE, title) 29 | .withString(BundleKey.URL, url) 30 | .navigation(); 31 | } 32 | 33 | 34 | public static void gotoSearchResult(String title) { 35 | ARouter 36 | .getInstance() 37 | .build(ARouterPath.searchResultFrgPath) 38 | .withString(BundleKey.TITLE, title) 39 | .navigation(); 40 | } 41 | 42 | public static void gotoCollectList() { 43 | ARouter 44 | .getInstance() 45 | .build(ARouterPath.userCollectAcPath) 46 | .navigation(); 47 | } 48 | 49 | public static void startArticleTabViewPagerAct(CategoryBean bean, int index) { 50 | ARouter 51 | .getInstance() 52 | .build(ARouterPath.articleTabViewPagerAcPath) 53 | .withInt("index", index) 54 | .withParcelable("category", bean) 55 | .navigation(); 56 | } 57 | 58 | public static void login() { 59 | ARouter 60 | .getInstance() 61 | .build(ARouterPath.loginPath) 62 | .navigation(); 63 | 64 | } 65 | 66 | public static void gotoMain() { 67 | ARouter 68 | .getInstance() 69 | .build(ARouterPath.mainPath) 70 | .navigation(); 71 | 72 | } 73 | 74 | public static void about() { 75 | ARouter 76 | .getInstance() 77 | .build(ARouterPath.aboutActPath) 78 | .navigation(); 79 | 80 | } 81 | 82 | public static void setting() { 83 | ARouter 84 | .getInstance() 85 | .build(ARouterPath.settingActPath) 86 | .navigation(); 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/arouter/ARouterPath.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.arouter; 2 | 3 | /** 4 | *
5 | * @author : xiaoyao 6 | * e-mail : xiaoyao@51vest.com 7 | * date : 2018/07/26 8 | * desc : 页面路径 9 | * version : 1.0 10 | *11 | */ 12 | public interface ARouterPath { 13 | String mainPath = "/app/main/activity"; 14 | String mainHomePath = "/app/home/fragment"; 15 | String mainMinePath = "/app/home/mine"; 16 | String loginPath = "/app/login/activity"; 17 | String webViewPath = "/article/details/webView/activity"; 18 | String categoryPath = "/article/category/fragment"; 19 | String articleTabViewPagerAcPath = "/article/tab_viewpager/activity"; 20 | String articleListFrPath = "/article/list/fragment"; 21 | String userCollectAcPath = "/user/collect/activity"; 22 | String searchActPath = "/search/activity"; 23 | String searchResultFrgPath = "/search/result/fragment"; 24 | String aboutActPath = "/mine/about/activity"; 25 | String settingActPath = "/mine/setting/activity"; 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/arouter/LoginInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.arouter; 2 | 3 | import android.content.Context; 4 | 5 | import com.alibaba.android.arouter.facade.Postcard; 6 | import com.alibaba.android.arouter.facade.annotation.Interceptor; 7 | import com.alibaba.android.arouter.facade.callback.InterceptorCallback; 8 | import com.alibaba.android.arouter.facade.template.IInterceptor; 9 | import com.alibaba.android.arouter.launcher.ARouter; 10 | import com.allen.library.RxHttpUtils; 11 | 12 | /** 13 | *
14 | * @author : xiaoyao 15 | * e-mail : xiaoyao@51vest.com 16 | * date : 2018/07/26 17 | * desc : 登录拦截器 18 | * version : 1.0 19 | *20 | */ 21 | @Interceptor(priority = 1) 22 | public class LoginInterceptor implements IInterceptor { 23 | @Override 24 | public void process(Postcard postcard, InterceptorCallback callback) { 25 | 26 | if (postcard.getPath().equals(ARouterPath.userCollectAcPath)) { 27 | if (RxHttpUtils.getAllCookie().size() > 0) { 28 | callback.onContinue(postcard); 29 | } else { 30 | callback.onInterrupt(null); 31 | ARouter.getInstance().build(ARouterPath.loginPath).navigation(); 32 | } 33 | } else { 34 | callback.onContinue(postcard); 35 | } 36 | 37 | } 38 | 39 | @Override 40 | public void init(Context context) { 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/bean/BannerBean.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.bean; 2 | 3 | /** 4 | *
5 | * @author : Allen 6 | * e-mail : lygttpod@163.com 7 | * date : 2018/07/22 8 | * desc : 9 | * version : 1.0 10 | *11 | */ 12 | public class BannerBean { 13 | 14 | /** 15 | * desc : 16 | * id : 15 17 | * imagePath : http://www.wanandroid.com/blogimgs/ec492618-d03e-4380-81df-5a990228a37e.jpg 18 | * isVisible : 1 19 | * order : 0 20 | * title : 当当网图书满200立减120,满400-250,本站福利 21 | * type : 0 22 | * url : http://www.wanandroid.com/blog/show/2234 23 | */ 24 | 25 | private String desc; 26 | private int id; 27 | private String imagePath; 28 | private int isVisible; 29 | private int order; 30 | private String title; 31 | private int type; 32 | private String url; 33 | 34 | public String getDesc() { 35 | return desc; 36 | } 37 | 38 | public void setDesc(String desc) { 39 | this.desc = desc; 40 | } 41 | 42 | public int getId() { 43 | return id; 44 | } 45 | 46 | public void setId(int id) { 47 | this.id = id; 48 | } 49 | 50 | public String getImagePath() { 51 | return imagePath; 52 | } 53 | 54 | public void setImagePath(String imagePath) { 55 | this.imagePath = imagePath; 56 | } 57 | 58 | public int getIsVisible() { 59 | return isVisible; 60 | } 61 | 62 | public void setIsVisible(int isVisible) { 63 | this.isVisible = isVisible; 64 | } 65 | 66 | public int getOrder() { 67 | return order; 68 | } 69 | 70 | public void setOrder(int order) { 71 | this.order = order; 72 | } 73 | 74 | public String getTitle() { 75 | return title; 76 | } 77 | 78 | public void setTitle(String title) { 79 | this.title = title; 80 | } 81 | 82 | public int getType() { 83 | return type; 84 | } 85 | 86 | public void setType(int type) { 87 | this.type = type; 88 | } 89 | 90 | public String getUrl() { 91 | return url; 92 | } 93 | 94 | public void setUrl(String url) { 95 | this.url = url; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/bean/HotBean.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.bean; 2 | 3 | /** 4 | *
5 | * @author : xiaoyao 6 | * e-mail : xiaoyao@51vest.com 7 | * date : 2018/07/27 8 | * desc : 9 | * version : 1.0 10 | *11 | */ 12 | public class HotBean { 13 | 14 | /** 15 | * icon : 16 | * id : 17 17 | * link : http://www.wanandroid.com/article/list/0?cid=176 18 | * name : 国内大牛博客集合 19 | * order : 1 20 | * visible : 1 21 | */ 22 | 23 | private String icon; 24 | private int id; 25 | private String link; 26 | private String name; 27 | private int order; 28 | private int visible; 29 | 30 | public String getIcon() { 31 | return icon; 32 | } 33 | 34 | public void setIcon(String icon) { 35 | this.icon = icon; 36 | } 37 | 38 | public int getId() { 39 | return id; 40 | } 41 | 42 | public void setId(int id) { 43 | this.id = id; 44 | } 45 | 46 | public String getLink() { 47 | return link; 48 | } 49 | 50 | public void setLink(String link) { 51 | this.link = link; 52 | } 53 | 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | public void setName(String name) { 59 | this.name = name; 60 | } 61 | 62 | public int getOrder() { 63 | return order; 64 | } 65 | 66 | public void setOrder(int order) { 67 | this.order = order; 68 | } 69 | 70 | public int getVisible() { 71 | return visible; 72 | } 73 | 74 | public void setVisible(int visible) { 75 | this.visible = visible; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/broadcast/LoginBroadcastReceiver.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.broadcast; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | import com.allen.library.utils.SPUtils; 8 | import com.allen.wanandroid.ui.login.LoginActivity; 9 | 10 | import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 11 | 12 | /** 13 | *
14 | * @author : xiaoyao 15 | * e-mail : xiaoyao@51vest.com 16 | * date : 2018/08/01 17 | * desc : 18 | * version : 1.0 19 | *20 | */ 21 | public class LoginBroadcastReceiver extends BroadcastReceiver { 22 | @Override 23 | public void onReceive(Context context, Intent intent) { 24 | if (intent != null && intent.getAction() != null) { 25 | String s = intent.getAction(); 26 | if (s.equals("com.allen.wan_android.need_login_action")) { 27 | SPUtils.clearAll(); 28 | Intent login = new Intent(); 29 | login.setClass(context, LoginActivity.class); 30 | login.setFlags(FLAG_ACTIVITY_NEW_TASK); 31 | context.startActivity(login); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/constant/BundleKey.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.constant; 2 | 3 | /** 4 | *
5 | * @author : Allen 6 | * e-mail : lygttpod@163.com 7 | * date : 2018/07/22 8 | * desc : 9 | * version : 1.0 10 | *11 | */ 12 | public interface BundleKey { 13 | String TITLE = "title"; 14 | String URL = "url"; 15 | String ID = "id"; 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/db/DaoSession.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.db; 2 | 3 | import java.util.Map; 4 | 5 | import org.greenrobot.greendao.AbstractDao; 6 | import org.greenrobot.greendao.AbstractDaoSession; 7 | import org.greenrobot.greendao.database.Database; 8 | import org.greenrobot.greendao.identityscope.IdentityScopeType; 9 | import org.greenrobot.greendao.internal.DaoConfig; 10 | 11 | import com.allen.wanandroid.bean.UserBean; 12 | 13 | import com.allen.wanandroid.db.UserBeanDao; 14 | 15 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. 16 | 17 | /** 18 | * {@inheritDoc} 19 | * 20 | * @see org.greenrobot.greendao.AbstractDaoSession 21 | */ 22 | public class DaoSession extends AbstractDaoSession { 23 | 24 | private final DaoConfig userBeanDaoConfig; 25 | 26 | private final UserBeanDao userBeanDao; 27 | 28 | public DaoSession(Database db, IdentityScopeType type, Map
10 | * @author : xiaoyao 11 | * e-mail : xiaoyao@51vest.com 12 | * date : 2018/07/26 13 | * desc : 14 | * version : 1.0 15 | *16 | */ 17 | public class StringConverter implements PropertyConverter
11 | * @author : Allen 12 | * e-mail : lygttpod@163.com 13 | * date : 2018/07/21 14 | * desc : 15 | * version : 1.0 16 | *17 | */ 18 | public interface ArticleView extends IBaseMvpView { 19 | 20 | void showBanner(List
12 | * @author : xiaoyao 13 | * e-mail : xiaoyao@51vest.com 14 | * date : 2018/07/23 15 | * desc : 16 | * version : 1.0 17 | *18 | */ 19 | public class CategoryHomePresenter extends BaseMvpPresenter
11 | * @author : xiaoyao 12 | * e-mail : xiaoyao@51vest.com 13 | * date : 2018/07/23 14 | * desc : 15 | * version : 1.0 16 | *17 | */ 18 | public interface CategoryHomeView extends IBaseMvpView { 19 | void showCategoryList(List
11 | * @author : Allen 12 | * e-mail : lygttpod@163.com 13 | * date : 2018/07/21 14 | * desc : 15 | * version : 1.0 16 | *17 | */ 18 | public class CollectPresenter extends BaseMvpPresenter
11 | * @author : Allen 12 | * e-mail : lygttpod@163.com 13 | * date : 2018/07/21 14 | * desc : 15 | * version : 1.0 16 | *17 | */ 18 | public interface CollectView extends IBaseMvpView { 19 | 20 | void showNewArticleList(List
11 | * @author : xiaoyao 12 | * e-mail : xiaoyao@51vest.com 13 | * date : 2018/07/25 14 | * desc : 15 | * version : 1.0 16 | *17 | */ 18 | public class LoginPresenter extends BaseMvpPresenter
8 | * @author : xiaoyao 9 | * e-mail : xiaoyao@51vest.com 10 | * date : 2018/07/25 11 | * desc : 12 | * version : 1.0 13 | *14 | */ 15 | public interface LoginView extends IBaseMvpView { 16 | 17 | String getUserName(); 18 | String getPassWord(); 19 | String getRePassWord(); 20 | 21 | void optionSuccess(UserBean userBean); 22 | void optionError(String error); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/ui/mine/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.ui.mine; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.support.design.widget.CollapsingToolbarLayout; 7 | import android.support.v7.widget.Toolbar; 8 | import android.text.Html; 9 | import android.view.View; 10 | import android.widget.TextView; 11 | 12 | import com.alibaba.android.arouter.facade.annotation.Route; 13 | import com.allen.wanandroid.BuildConfig; 14 | import com.allen.wanandroid.R; 15 | import com.allen.wanandroid.arouter.ARouterPath; 16 | import com.library.base.base.BaseActivity; 17 | import com.library.base.widget.TopBar; 18 | 19 | import butterknife.BindView; 20 | 21 | /** 22 | *
23 | * @author : xiaoyao 24 | * e-mail : xiaoyao@51vest.com 25 | * date : 2018/08/03 26 | * desc : 关于我们 27 | * version : 1.0 28 | *29 | */ 30 | @Route(path = ARouterPath.aboutActPath) 31 | public class AboutActivity extends BaseActivity { 32 | @BindView(R.id.toolbar) 33 | Toolbar toolbar; 34 | @BindView(R.id.about_tv) 35 | TextView aboutTv; 36 | @BindView(R.id.toolbar_layout) 37 | CollapsingToolbarLayout toolbarLayout; 38 | @BindView(R.id.version_tv) 39 | TextView versionTv; 40 | 41 | @Override 42 | protected void getBundleData(Bundle params) { 43 | 44 | } 45 | 46 | @Override 47 | public int bindLayout() { 48 | return R.layout.activity_about; 49 | } 50 | 51 | @Override 52 | public void setTopBar(TopBar topBar) { 53 | hideTopBar(); 54 | } 55 | 56 | @Override 57 | public boolean isCanRefresh() { 58 | return false; 59 | } 60 | 61 | @Override 62 | public void doOnRefresh() { 63 | 64 | } 65 | 66 | @Override 67 | public void initUI(Context context) { 68 | 69 | } 70 | 71 | @Override 72 | public void doBusiness(Context context) { 73 | versionTv.setText(BuildConfig.VERSION_NAME); 74 | toolbarLayout.setExpandedTitleColor(Color.WHITE);//设置展开后标题的颜色 75 | toolbarLayout.setCollapsedTitleTextColor(Color.WHITE);//设置收缩后标题的颜色 76 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 77 | @Override 78 | public void onClick(View v) { 79 | finish(); 80 | } 81 | }); 82 | aboutTv.setText(Html.fromHtml(getResources().getString(R.string.about_content))); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/ui/mine/MineHomeFragment.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.ui.mine; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.widget.TextView; 6 | 7 | import com.alibaba.android.arouter.facade.annotation.Route; 8 | import com.allen.wanandroid.R; 9 | import com.allen.wanandroid.arouter.ARouterPath; 10 | import com.library.base.mvp.BaseMvpFragment; 11 | import com.library.base.widget.TopBar; 12 | 13 | import butterknife.BindView; 14 | import butterknife.OnClick; 15 | 16 | /** 17 | *
18 | * @author : xiaoyao 19 | * e-mail : xiaoyao@51vest.com 20 | * date : 2018/07/26 21 | * desc : 我的页面 22 | * version : 1.0 23 | *24 | */ 25 | @Route(path = ARouterPath.mainMinePath) 26 | public class MineHomeFragment extends BaseMvpFragment
10 | * @author : xiaoyao 11 | * e-mail : xiaoyao@51vest.com 12 | * date : 2018/07/26 13 | * desc : 14 | * version : 1.0 15 | *16 | */ 17 | public class MineHomePresenter extends BaseMvpPresenter
7 | * @author : xiaoyao 8 | * e-mail : xiaoyao@51vest.com 9 | * date : 2018/07/26 10 | * desc : 11 | * version : 1.0 12 | *13 | */ 14 | public interface MineHomeView extends IBaseMvpView { 15 | void setUserName(String userName); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/ui/project/ProjectArticlePresenter.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.ui.project; 2 | 3 | import com.allen.library.observer.DataObserver; 4 | import com.allen.wanandroid.api.ApiModel; 5 | import com.allen.wanandroid.bean.HomeBean; 6 | import com.library.base.mvp.BaseMvpPresenter; 7 | 8 | 9 | /** 10 | *
11 | * @author : Allen 12 | * e-mail : lygttpod@163.com 13 | * date : 2018/07/21 14 | * desc : 15 | * version : 1.0 16 | *17 | */ 18 | public class ProjectArticlePresenter extends BaseMvpPresenter
10 | * @author : Allen 11 | * e-mail : lygttpod@163.com 12 | * date : 2018/07/21 13 | * desc : 14 | * version : 1.0 15 | *16 | */ 17 | public interface ProjectArticleView extends IBaseMvpView { 18 | 19 | void showNewArticleList(List
13 | * @author : xiaoyao 14 | * e-mail : xiaoyao@51vest.com 15 | * date : 2018/07/27 16 | * desc : 17 | * version : 1.0 18 | *19 | */ 20 | public class ProjectHomePresenter extends BaseMvpPresenter
10 | * @author : xiaoyao 11 | * e-mail : xiaoyao@51vest.com 12 | * date : 2018/07/27 13 | * desc : 14 | * version : 1.0 15 | *16 | */ 17 | public interface ProjectHomeView extends IBaseMvpView { 18 | 19 | void setTabData(List
13 | * @author : xiaoyao 14 | * e-mail : xiaoyao@51vest.com 15 | * date : 2018/07/27 16 | * desc : 17 | * version : 1.0 18 | *19 | */ 20 | public class SearchPresenter extends BaseMvpPresenter
10 | * @author : xiaoyao 11 | * e-mail : xiaoyao@51vest.com 12 | * date : 2018/07/27 13 | * desc : 14 | * version : 1.0 15 | *16 | */ 17 | public interface SearchViewView extends IBaseMvpView { 18 | 19 | void setHotSearchData(List
9 | * @author : xiaoyao 10 | * e-mail : xiaoyao@51vest.com 11 | * date : 2018/07/25 12 | * desc : 13 | * version : 1.0 14 | *15 | */ 16 | public interface WebViewView extends IBaseMvpView{ 17 | 18 | ProgressBar getProgressBar(); 19 | 20 | void setTitle(String title); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/utils/DbUtils.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.utils; 2 | 3 | import com.allen.wanandroid.app.App; 4 | import com.allen.wanandroid.bean.UserBean; 5 | import com.allen.wanandroid.db.UserBeanDao; 6 | 7 | /** 8 | *
9 | * @author : xiaoyao 10 | * e-mail : xiaoyao@51vest.com 11 | * date : 2018/07/26 12 | * desc : 13 | * version : 1.0 14 | *15 | */ 16 | public class DbUtils { 17 | public static UserBeanDao getUserDao() { 18 | return App.getDaoSession().getUserBeanDao(); 19 | } 20 | 21 | /** 22 | * 插入数据库操作 23 | */ 24 | public static void insertUserInfo(UserBean userBean) { 25 | UserBean user = getUserDao() 26 | .queryBuilder() 27 | .where(UserBeanDao.Properties.Id.eq(userBean.getId())) 28 | .build() 29 | .unique(); 30 | if (null != user) { 31 | deleteUserInfo(userBean); 32 | } 33 | getUserDao().insert(userBean); 34 | } 35 | 36 | /** 37 | * 删除某行数据 38 | * 39 | * @param userBean 40 | */ 41 | public static void deleteUserInfo(UserBean userBean) { 42 | getUserDao().delete(userBean); 43 | } 44 | 45 | public static UserBean queryUserInfo(){ 46 | UserBean user = getUserDao() 47 | .queryBuilder() 48 | .build() 49 | .unique(); 50 | return user; 51 | } 52 | public static boolean isQueryUser(){ 53 | return null!=queryUserInfo(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/utils/DisplayUtils.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.utils; 2 | 3 | import android.util.DisplayMetrics; 4 | 5 | import com.allen.wanandroid.app.App; 6 | 7 | 8 | /** 9 | *
10 | * @author : xiaoyao 11 | * e-mail : xiaoyao@51vest.com 12 | * date : 2018/02/05 13 | * desc : 屏幕信息有关的类,包括屏幕的长宽、分辨率、长度换算 14 | * version : 1.0 15 | *16 | */ 17 | public class DisplayUtils { 18 | 19 | private static DisplayMetrics metrics; 20 | 21 | static { 22 | metrics = App.getContext().getResources().getDisplayMetrics(); 23 | } 24 | 25 | public static DisplayMetrics getDisplayMetrics() { 26 | return metrics; 27 | } 28 | 29 | /** 30 | * 获取屏幕的像素密度(DPI) 31 | * 32 | * @return 33 | */ 34 | public static int getDpi() { 35 | return (int) (metrics.density * 160); 36 | } 37 | 38 | /** 39 | * 获取px与dp的比值,比如返回2,1dp=2px 40 | */ 41 | public static float getDensity() { 42 | return metrics.density; 43 | } 44 | 45 | /** 46 | * 获取屏幕宽度,以像素为单位 47 | * 48 | * @return 49 | */ 50 | public static int getScreenWidth() { 51 | return metrics.widthPixels; 52 | } 53 | 54 | /** 55 | * 获取屏幕高度,以像素为单位 56 | * 57 | * @return 58 | */ 59 | public static int getScreenHeight() { 60 | return metrics.heightPixels; 61 | } 62 | 63 | /** 64 | * 字体大小单位由sp转为px 65 | * 66 | * @param spValue 原sp单位 67 | * @return 新的px单位 68 | */ 69 | public static int sp2px(float spValue) { 70 | final float fontScale = metrics.scaledDensity; 71 | return (int) (spValue * fontScale + 0.5f); 72 | } 73 | 74 | /** 75 | * 字体大小由px转为sp 76 | * 77 | * @param pxValue 原px单位 78 | * @return 新的sp单位 79 | */ 80 | public static int px2sp(float pxValue) { 81 | final float fontScale = metrics.scaledDensity; 82 | return (int) (pxValue / fontScale + 0.5f); 83 | } 84 | 85 | /** 86 | * 长度单位由dp转为px 87 | * 88 | * @param dpValue 原dp单位 89 | * @return 转换后的px单位 90 | */ 91 | public static int dp2px(float dpValue) { 92 | final float density = getDensity(); 93 | return (int) (dpValue * density + 0.5f); 94 | } 95 | 96 | /** 97 | * 长度单位由px转为dp 98 | * 99 | * @param pxValue 原px单位 100 | * @return 转换后的dp单位 101 | */ 102 | public static int px2dp(float pxValue) { 103 | final float density = getDensity(); 104 | return (int) (pxValue / density + 0.5f); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/java/com/allen/wanandroid/widget/CustomViewPager.java: -------------------------------------------------------------------------------- 1 | package com.allen.wanandroid.widget; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.view.ViewPager; 7 | import android.util.AttributeSet; 8 | import android.view.MotionEvent; 9 | 10 | /** 11 | *
12 | * @author : Allen 13 | * e-mail : lygttpod@163.com 14 | * date : 2018/08/04 15 | * desc : 禁止左右滑动和去除切换动画的viewPager 16 | * version : 1.0 17 | *18 | */ 19 | public class CustomViewPager extends ViewPager{ 20 | public CustomViewPager(@NonNull Context context) { 21 | super(context); 22 | } 23 | 24 | public CustomViewPager(@NonNull Context context, @Nullable AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | @Override 29 | public void setCurrentItem(int item) { 30 | super.setCurrentItem(item,false); 31 | } 32 | 33 | @Override 34 | public void setCurrentItem(int item, boolean smoothScroll) { 35 | super.setCurrentItem(item, smoothScroll); 36 | } 37 | 38 | @Override 39 | protected boolean dispatchGenericFocusedEvent(MotionEvent event) { 40 | return super.dispatchGenericFocusedEvent(event); 41 | } 42 | 43 | @Override 44 | public boolean onInterceptTouchEvent(MotionEvent ev) { 45 | return false; 46 | } 47 | 48 | @Override 49 | public boolean onTouchEvent(MotionEvent ev) { 50 | return false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 |
\t\t本网站每天新增20~30篇优质文章,并加入到现有分类中,力求整理出一份优质而又详尽的知识体系,闲暇时间不妨上来学习下知识;除此以外,并为大家提供平时开发过程中常用的工具以及常用的网址导航。
7 |\t\t当然这只是我们目前的功能,未来我们将提供更多更加便捷的功能…
8 |\t\t如果您有任何好的建议:
9 |\t\t可以在 https://github.com/hongyangAndroid/xueandroid 项目中以issue的形式提出,我将及时跟进。
13 |\t\t如果您希望长期关注本站,可以加入我们的QQ群:591683946
14 |\t\t本软件开源,如果你发现任何错误,不要犹豫,马上点击GitHub,在上面发起issue或者提交pull request。
16 | ]]>
16 | * 基类BaseObserver使用BaseData
17 | */
18 |
19 | public abstract class BaseDataObserver
17 | * 基类BaseObserver
18 | */
19 |
20 | public abstract class BaseObserver
15 | * 结果不做处理直接返回string
16 | */
17 |
18 | public abstract class BaseStringObserver implements Observer
8 | * 返回数据基类
9 | */
10 |
11 | public class BaseData
6 | *
7 | * @author Allen
8 | * 存放SharedPreferences文件的所有Key值
9 | */
10 |
11 | public interface SPKeys {
12 |
13 | /**
14 | * 保存cookie
15 | */
16 | String COOKIE = "cookie";
17 | /**
18 | * 服务器相应时间
19 | */
20 | String DATE = "date";
21 | }
22 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/cookie/CookieJarImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 jeasonlzy(廖子尧)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.allen.library.cookie;
17 |
18 |
19 | import com.allen.library.cookie.store.CookieStore;
20 |
21 | import java.util.List;
22 |
23 | import okhttp3.Cookie;
24 | import okhttp3.CookieJar;
25 | import okhttp3.HttpUrl;
26 |
27 | /**
28 | * ================================================
29 | * 作 者:jeasonlzy(廖子尧)Github地址:https://github.com/jeasonlzy
30 | * 版 本:1.0
31 | * 创建日期:2016/1/12
32 | * 描 述:CookieJar的实现类,默认管理了用户自己维护的cookie
33 | * 修订历史:
34 | * ================================================
35 | */
36 | public class CookieJarImpl implements CookieJar {
37 |
38 | private CookieStore cookieStore;
39 |
40 | public CookieJarImpl(CookieStore cookieStore) {
41 | if (cookieStore == null) {
42 | throw new IllegalArgumentException("cookieStore can not be null!");
43 | }
44 | this.cookieStore = cookieStore;
45 | }
46 |
47 | @Override
48 | public synchronized void saveFromResponse(HttpUrl url, List
12 | *
13 | * @author Allen
14 | * 下载文件
15 | */
16 |
17 | public interface DownloadApi {
18 |
19 |
20 | /**
21 | * 大文件官方建议用 @Streaming 来进行注解,不然会出现IO异常,小文件可以忽略不注入
22 | *
23 | * @param fileUrl 地址
24 | * @return ResponseBody
25 | */
26 | @Streaming
27 | @GET
28 | Observable
16 | *
17 | * @author Allen
18 | * 保存下载的文件
19 | */
20 |
21 | public class DownloadManager {
22 |
23 |
24 | /**
25 | * 保存文件
26 | *
27 | * @param response ResponseBody
28 | * @param destFileName 文件名(包括文件后缀)
29 | * @return 返回
30 | * @throws IOException
31 | */
32 | public File saveFile(ResponseBody response, final String destFileName, ProgressListener progressListener) throws IOException {
33 |
34 | String destFileDir = RxHttpUtils.getContext().getExternalFilesDir(null) + File.separator;
35 |
36 | long contentLength = response.contentLength();
37 | InputStream is = null;
38 | byte[] buf = new byte[2048];
39 | int len = 0;
40 | FileOutputStream fos = null;
41 | try {
42 | is = response.byteStream();
43 |
44 | long sum = 0;
45 |
46 | File dir = new File(destFileDir);
47 | if (!dir.exists()) {
48 | dir.mkdirs();
49 | }
50 | File file = new File(dir, destFileName);
51 | fos = new FileOutputStream(file);
52 | while ((len = is.read(buf)) != -1) {
53 | sum += len;
54 | fos.write(buf, 0, len);
55 |
56 | final long finalSum = sum;
57 |
58 | progressListener.onResponseProgress(finalSum, contentLength, (int) ((finalSum * 1.0f / contentLength) * 100), finalSum == contentLength, file.getAbsolutePath());
59 | }
60 | fos.flush();
61 |
62 | return file;
63 |
64 | } finally {
65 | try {
66 | response.close();
67 | if (is != null)
68 | is.close();
69 | } catch (IOException e) {
70 | }
71 | try {
72 | if (fos != null)
73 | fos.close();
74 | } catch (IOException e) {
75 | }
76 |
77 | }
78 | }
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/download/DownloadRetrofit.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.download;
2 |
3 |
4 | import com.allen.library.http.RetrofitClient;
5 | import com.allen.library.interceptor.Transformer;
6 |
7 | import io.reactivex.Observable;
8 | import okhttp3.ResponseBody;
9 | import retrofit2.Retrofit;
10 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
11 | import retrofit2.converter.gson.GsonConverterFactory;
12 |
13 | /**
14 | * Created by allen on 2017/6/14.
15 | *
16 | *
17 | * @author Allen
18 | * 为下载单独建一个retrofit
19 | */
20 |
21 | public class DownloadRetrofit {
22 |
23 | private static DownloadRetrofit instance;
24 | private Retrofit mRetrofit;
25 |
26 | private static String baseUrl = "https://api.github.com/";
27 |
28 |
29 | public DownloadRetrofit() {
30 | mRetrofit = new Retrofit.Builder()
31 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
32 | .addConverterFactory(GsonConverterFactory.create())
33 | .baseUrl(baseUrl)
34 | .build();
35 | }
36 |
37 | public static DownloadRetrofit getInstance() {
38 |
39 | if (instance == null) {
40 | synchronized (RetrofitClient.class) {
41 | if (instance == null) {
42 | instance = new DownloadRetrofit();
43 | }
44 | }
45 |
46 | }
47 | return instance;
48 | }
49 |
50 | public Retrofit getRetrofit() {
51 | return mRetrofit;
52 | }
53 |
54 | public static Observable
6 | *
7 | * @author Allen
8 | * 下载监听
9 | */
10 |
11 | public interface ProgressListener {
12 |
13 | /**
14 | * 载进度监听
15 | *
16 | * @param bytesRead 已经下载文件的大小
17 | * @param contentLength 文件的大小
18 | * @param progress 当前进度
19 | * @param done 是否下载完成
20 | * @param filePath 文件路径
21 | */
22 | void onResponseProgress(long bytesRead, long contentLength, int progress, boolean done, String filePath);
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/gson/DoubleDefault0Adapter.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.gson;
2 |
3 | import com.google.gson.JsonDeserializationContext;
4 | import com.google.gson.JsonDeserializer;
5 | import com.google.gson.JsonElement;
6 | import com.google.gson.JsonParseException;
7 | import com.google.gson.JsonPrimitive;
8 | import com.google.gson.JsonSerializationContext;
9 | import com.google.gson.JsonSerializer;
10 | import com.google.gson.JsonSyntaxException;
11 |
12 | import java.lang.reflect.Type;
13 |
14 | /**
15 | * Created by Allen on 2017/11/20.
16 | *
17 | * 定义为double类型,如果后台返回""或者null,则返回0.00
18 | */
19 |
20 | public class DoubleDefault0Adapter implements JsonSerializer
17 | * 定义为int类型,如果后台返回""或者null,则返回0
18 | */
19 |
20 | public class IntegerDefault0Adapter implements JsonSerializer
17 | * 定义为long类型,如果后台返回""或者null,则返回0
18 | */
19 |
20 | public class LongDefault0Adapter implements JsonSerializer
11 | *
12 | * @author Allen
13 | * 网络请求工具类---使用的是全局配置的变量
14 | */
15 |
16 | public class GlobalRxHttp {
17 |
18 | private static GlobalRxHttp instance;
19 |
20 | /**
21 | * 缓存retrofit针对同一个ApiService不会重复创建retrofit对象
22 | */
23 | private static HashMap
8 | *
9 | * @author Allen
10 | * okHttp client
11 | */
12 |
13 | public class HttpClient {
14 |
15 | private static HttpClient instance;
16 |
17 | private OkHttpClient.Builder builder;
18 |
19 | public HttpClient() {
20 | builder = new OkHttpClient.Builder();
21 | }
22 |
23 | public static HttpClient getInstance() {
24 |
25 | if (instance == null) {
26 | synchronized (HttpClient.class) {
27 | if (instance == null) {
28 | instance = new HttpClient();
29 | }
30 | }
31 |
32 | }
33 | return instance;
34 | }
35 |
36 |
37 | public OkHttpClient.Builder getBuilder() {
38 | return builder;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/interceptor/AddCookiesInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.interceptor;
2 |
3 | import android.util.Log;
4 |
5 | import com.allen.library.constant.SPKeys;
6 | import com.allen.library.utils.SPUtils;
7 |
8 | import java.io.IOException;
9 | import java.util.HashSet;
10 |
11 | import okhttp3.Interceptor;
12 | import okhttp3.Request;
13 | import okhttp3.Response;
14 |
15 | /**
16 | * Created by Allen on 2017/5/11.
17 | *
18 | *
19 | * @author Allen
20 | * 请求头里边添加cookie
21 | */
22 |
23 | public class AddCookiesInterceptor implements Interceptor {
24 | @Override
25 | public Response intercept(Chain chain) throws IOException {
26 | Request.Builder builder = chain.request().newBuilder();
27 | HashSet
14 | *
15 | * @author Allen
16 | * 请求拦截器 统一添加请求头使用
17 | */
18 |
19 | public class HeaderInterceptor implements Interceptor {
20 |
21 | private Map
16 | *
17 | * @author Allen
18 | * 接受服务器发的cookie 并保存到本地
19 | */
20 |
21 | public class ReceivedCookiesInterceptor implements Interceptor {
22 |
23 | @Override
24 | public Response intercept(Chain chain) throws IOException {
25 | Response originalResponse = chain.proceed(chain.request());
26 | //这里获取请求返回的cookie
27 | if (!originalResponse.headers("Set-Cookie").isEmpty()) {
28 | HashSet
20 | *
21 | * @author Allen
22 | * 控制操作线程的辅助类
23 | */
24 |
25 | public class Transformer {
26 |
27 | /**
28 | * 无参数
29 | *
30 | * @param
10 | *
11 | * @author Allen
12 | * 定义请求结果处理接口
13 | */
14 |
15 | public interface IDataSubscriber
8 | *
9 | * @author Allen
10 | * 定义请求结果处理接口
11 | */
12 |
13 | public interface IStringSubscriber {
14 |
15 | /**
16 | * doOnSubscribe 回调
17 | *
18 | * @param d Disposable
19 | */
20 | void doOnSubscribe(Disposable d);
21 |
22 | /**
23 | * 错误回调
24 | *
25 | * @param errorMsg 错误信息
26 | */
27 | void doOnError(String errorMsg);
28 |
29 | /**
30 | * 成功回调
31 | *
32 | * @param string data
33 | */
34 | void doOnNext(String string);
35 |
36 | /**
37 | * 请求完成回调
38 | */
39 | void doOnCompleted();
40 | }
41 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/interfaces/ISubscriber.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.interfaces;
2 |
3 | import io.reactivex.disposables.Disposable;
4 |
5 | /**
6 | * Created by allen on 2016/12/21.
7 | *
8 | *
9 | * @author Allen
10 | * 定义请求结果处理接口
11 | */
12 |
13 | public interface ISubscriber
19 | * 针对特定格式的时候设置的通用的Observer
20 | * 用户可以根据自己需求自定义自己的类继承BaseDataObserver
16 | * 自定义Observer 处理string回调
17 | */
18 |
19 | public abstract class StringObserver extends BaseStringObserver {
20 |
21 | /**
22 | * 失败回调
23 | *
24 | * @param errorMsg 错误信息
25 | */
26 | protected abstract void onError(String errorMsg);
27 |
28 | /**
29 | * 成功回调
30 | *
31 | * @param data 结果
32 | */
33 | protected abstract void onSuccess(String data);
34 |
35 |
36 | @Override
37 | public void doOnSubscribe(Disposable d) {
38 | }
39 |
40 | @Override
41 | public void doOnError(String errorMsg) {
42 | if (!isHideToast() && !TextUtils.isEmpty(errorMsg)) {
43 | ToastUtils.showToast(errorMsg);
44 | }
45 | onError(errorMsg);
46 | }
47 |
48 | @Override
49 | public void doOnNext(String string) {
50 | onSuccess(string);
51 | }
52 |
53 |
54 | @Override
55 | public void doOnCompleted() {
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/upload/UploadFileApi.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.upload;
2 |
3 | import java.util.List;
4 |
5 | import io.reactivex.Observable;
6 | import okhttp3.MultipartBody;
7 | import okhttp3.ResponseBody;
8 | import retrofit2.http.Multipart;
9 | import retrofit2.http.POST;
10 | import retrofit2.http.Part;
11 | import retrofit2.http.Url;
12 |
13 | /**
14 | * Created by allen on 2017/6/15.
15 | *
16 | *
17 | * @author Allen
18 | * 文件上传
19 | */
20 |
21 | public interface UploadFileApi {
22 |
23 | /**
24 | * 上传
25 | *
26 | * @param uploadUrl 地址
27 | * @param file 文件
28 | * @return ResponseBody
29 | */
30 | @Multipart
31 | @POST
32 | Observable
18 | * 关于应用的工具类
19 | */
20 |
21 | public class AppUtils {
22 |
23 | /**
24 | * 获取手机版本号
25 | *
26 | * @return 返回版本号
27 | */
28 | public static String getAppVersion() {
29 | PackageInfo pi;
30 | String versionNum;
31 | try {
32 | PackageManager pm = RxHttpUtils.getContext().getPackageManager();
33 | pi = pm.getPackageInfo(RxHttpUtils.getContext().getPackageName(), PackageManager.GET_CONFIGURATIONS);
34 | versionNum = pi.versionName;
35 | } catch (Exception e) {
36 | versionNum = "0";
37 | }
38 | return versionNum;
39 | }
40 |
41 | /**
42 | * 获取手机唯一标识码UUID
43 | *
44 | * @return 返回UUID
45 | *
46 | * 记得添加相应权限
47 | * android.permission.READ_PHONE_STATE
48 | */
49 | public static String getUUID() {
50 |
51 | Context context = RxHttpUtils.getContext();
52 |
53 | String uuid = (String) SPUtils.get(context, "PHONE_UUID", "");
54 |
55 | if (TextUtils.isEmpty(uuid)) {
56 |
57 | try {
58 | TelephonyManager telephonyManager = (TelephonyManager) context
59 | .getSystemService(Context.TELEPHONY_SERVICE);
60 | @SuppressLint({"MissingPermission", "HardwareIds"}) String tmDevice = telephonyManager.getDeviceId();
61 | @SuppressLint({"MissingPermission", "HardwareIds"}) String tmSerial = telephonyManager.getSimSerialNumber();
62 |
63 | @SuppressLint("HardwareIds") String androidId = android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
64 | UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
65 | String uniqueId = deviceUuid.toString();
66 | uuid = uniqueId;
67 | SPUtils.put(context, "PHONE_UUID", uuid);
68 |
69 | } catch (Exception e) {
70 | e.printStackTrace();
71 | }
72 |
73 | }
74 |
75 | return uuid;
76 |
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/utils/MD5.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.utils;
2 |
3 | import java.security.MessageDigest;
4 | import java.security.NoSuchAlgorithmException;
5 |
6 |
7 | /**
8 | * MD5加密类
9 | */
10 | public class MD5 {
11 |
12 | //加的盐
13 | private static final String SALT = "HXWcjvQWVG1wI4FQBLZpQ3pWj48AV63d";
14 |
15 | public static String EncoderByMd5(String buf) {
16 | try {
17 | MessageDigest digist = MessageDigest.getInstance("MD5");
18 | byte[] rs = digist.digest(buf.getBytes());
19 | StringBuffer digestHexStr = new StringBuffer();
20 | for (int i = 0; i < 16; i++) {
21 | digestHexStr.append(byteHEX(rs[i]));
22 | }
23 | return digestHexStr.toString();
24 | } catch (NoSuchAlgorithmException e) {
25 | e.printStackTrace();
26 | }
27 | return null;
28 | }
29 |
30 | /**
31 | * 加盐的md5值。这样即使被拖库,仍然可以有效抵御彩虹表攻击
32 | *
33 | * @param inbuf 需做md5的字符串
34 | * @return
35 | */
36 | public static String encodeByMd5AndSalt(String inbuf) {
37 | return EncoderByMd5(EncoderByMd5(inbuf) + SALT);
38 | }
39 |
40 | public static String byteHEX(byte ib) {
41 | char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
42 | 'a', 'b', 'c', 'd', 'e', 'f'};
43 | char[] ob = new char[2];
44 | ob[0] = Digit[(ib >>> 4) & 0X0F];
45 | ob[1] = Digit[ib & 0X0F];
46 | String s = new String(ob);
47 | return s;
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/utils/NetUtils.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.utils;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.net.ConnectivityManager;
6 | import android.net.NetworkInfo;
7 |
8 | import com.allen.library.RxHttpUtils;
9 |
10 | /**
11 | *
10 | * 根据不同后台要求对post请求进行加工处理
11 | *
12 | * 用户根据自己需求编写自己的map操作类
13 | */
14 | public class ParamUtils {
15 |
16 | private Map extends BaseActivity implements IBaseMvpView {
17 |
18 | protected P mPresenter;
19 |
20 | protected abstract P createPresenter();
21 |
22 | @SuppressWarnings("unchecked")
23 | @Override
24 | protected void initPresenter() {
25 | super.initPresenter();
26 | mPresenter = createPresenter();
27 | if (null != mPresenter) {
28 | mPresenter.attachView(this);
29 | }
30 | }
31 |
32 | @Override
33 | protected void onDestroy() {
34 | super.onDestroy();
35 | if (null != mPresenter) {
36 | mPresenter.detachView();
37 | }
38 | }
39 |
40 | @Override
41 | public void showToast(String msg) {
42 | showToastMsg(msg);
43 | }
44 |
45 | @Override
46 | public Dialog getLoadingDialog() {
47 | return loadingDialog;
48 | }
49 |
50 | @Override
51 | public void showLoading() {
52 | showRefreshView();
53 | }
54 |
55 | @Override
56 | public void hideLoading() {
57 | hideRefreshView();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/mvp/BaseMvpFragment.java:
--------------------------------------------------------------------------------
1 | package com.library.base.mvp;
2 |
3 | import android.app.Dialog;
4 |
5 | import com.library.base.base.BaseFragment;
6 |
7 | /**
8 | * extends BaseFragment implements IBaseMvpView {
17 |
18 | protected P mPresenter;
19 |
20 | protected abstract P createPresenter();
21 |
22 | @SuppressWarnings("unchecked")
23 | @Override
24 | protected void initPresenter() {
25 | super.initPresenter();
26 | mPresenter = createPresenter();
27 | if (null != mPresenter) {
28 | mPresenter.attachView(this);
29 | }
30 | }
31 |
32 | @Override
33 | public void onDestroyView() {
34 | super.onDestroyView();
35 | if (null != mPresenter) {
36 | mPresenter.detachView();
37 | }
38 | }
39 |
40 | @Override
41 | public void showToast(String msg) {
42 | showToastMsg(msg);
43 | }
44 |
45 | @Override
46 | public Dialog getLoadingDialog() {
47 | return loadingDialog;
48 | }
49 |
50 | @Override
51 | public void showLoading() {
52 | showRefreshView();
53 | }
54 |
55 | @Override
56 | public void hideLoading() {
57 | hideRefreshView();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/mvp/BaseMvpPresenter.java:
--------------------------------------------------------------------------------
1 | package com.library.base.mvp;
2 |
3 | /**
4 | *
15 | * 安装更新的apk
16 | */
17 |
18 | public class InstallUtil {
19 |
20 |
21 | /**
22 | * 通过非Root模式安装
23 | *
24 | * @param context
25 | * @param apkPath
26 | * @param applicationId BuildConfig.APPLICATION_ID
27 | */
28 | public static void install(Context context, String applicationId, String apkPath) {
29 | //提升读写权限,否则可能出现解析异常
30 | setPermission(apkPath);
31 | installNormal(context, applicationId, apkPath);
32 | }
33 |
34 | /**
35 | * 提升读写权限
36 | *
37 | * @param filePath 文件路径
38 | * @return
39 | * @throws IOException
40 | */
41 | public static void setPermission(String filePath) {
42 | String command = "chmod " + "777" + " " + filePath;
43 | Runtime runtime = Runtime.getRuntime();
44 | try {
45 | runtime.exec(command);
46 | } catch (IOException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 |
51 | //普通安装
52 | private static void installNormal(Context context, String applicationId, String apkPath) {
53 | Intent intent = new Intent(Intent.ACTION_VIEW);
54 |
55 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
56 |
57 | //版本在7.0以上是不能直接通过uri访问的
58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
59 | File file = (new File(apkPath));
60 | //添加这一句表示对目标应用临时授权该Uri所代表的文件
61 | intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
62 | // 由于没有在Activity环境下启动Activity,设置下面的标签
63 | //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致 参数3 共享的文件
64 | Uri apkUri = FileProvider.getUriForFile(context, applicationId + ".fileprovider", file);
65 | intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
66 | } else {
67 | intent.setDataAndType(Uri.fromFile(new File(apkPath)),
68 | "application/vnd.android.package-archive");
69 | }
70 | context.startActivity(intent);
71 | ActivityCollector.finishAll();
72 | // Process.killProcess(Process.myPid());
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/utils/MathUtils.java:
--------------------------------------------------------------------------------
1 | package com.library.base.utils;
2 |
3 | import java.math.BigDecimal;
4 |
5 | /**
6 | * 加减乘除计算,防止精度丢失
7 | * Created by allen on 2016/9/7.
8 | */
9 | public class MathUtils {
10 |
11 |
12 | /**
13 | * 相加
14 | *
15 | * @param d1
16 | * @param d2
17 | * @return
18 | */
19 | public static double sum(double d1, double d2) {
20 | BigDecimal bd1 = new BigDecimal(Double.toString(d1));
21 | BigDecimal bd2 = new BigDecimal(Double.toString(d2));
22 | return bd1.add(bd2).doubleValue();
23 | }
24 |
25 |
26 | /**
27 | * 相减
28 | *
29 | * @param d1
30 | * @param d2
31 | * @return
32 | */
33 | public static double sub(double d1, double d2) {
34 | BigDecimal bd1 = new BigDecimal(Double.toString(d1));
35 | BigDecimal bd2 = new BigDecimal(Double.toString(d2));
36 | return bd1.subtract(bd2).doubleValue();
37 | }
38 |
39 | /**
40 | * 相乘
41 | *
42 | * @param d1
43 | * @param d2
44 | * @return
45 | */
46 | public static double mul(double d1, double d2) {
47 | BigDecimal bd1 = new BigDecimal(Double.toString(d1));
48 | BigDecimal bd2 = new BigDecimal(Double.toString(d2));
49 | return bd1.multiply(bd2).doubleValue();
50 | }
51 |
52 | /**
53 | * 相乘
54 | *
55 | * @param d1
56 | * @param d2
57 | * @return
58 | */
59 | public static int mul_int(double d1, double d2) {
60 | BigDecimal bd1 = new BigDecimal(Double.toString(d1));
61 | BigDecimal bd2 = new BigDecimal(Double.toString(d2));
62 | return bd1.multiply(bd2).intValue();
63 | }
64 |
65 | /**
66 | * 除法
67 | *
68 | * @param d1
69 | * @param d2
70 | * @param scale 四舍五入 小数点位数
71 | * @return
72 | */
73 | public static double div(double d1, double d2, int scale) {
74 | // 当然在此之前,你要判断分母是否为0,
75 | // 为0你可以根据实际需求做相应的处理
76 | BigDecimal bd1 = new BigDecimal(Double.toString(d1));
77 | BigDecimal bd2 = new BigDecimal(Double.toString(d2));
78 | return bd1.divide
79 | (bd2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
80 | }
81 |
82 | /**
83 | * 除法
84 | *
85 | * @param d1
86 | * @param d2
87 | * @return
88 | */
89 | public static double div(double d1, double d2) {
90 | // 当然在此之前,你要判断分母是否为0,
91 | // 为0你可以根据实际需求做相应的处理
92 | BigDecimal bd1 = new BigDecimal(Double.toString(d1));
93 | BigDecimal bd2 = new BigDecimal(Double.toString(d2));
94 | return bd1.divide(bd2, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
95 | }
96 |
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/utils/PhoneFormatUtils.java:
--------------------------------------------------------------------------------
1 | package com.library.base.utils;
2 |
3 | import android.widget.EditText;
4 |
5 | import java.util.regex.Matcher;
6 | import java.util.regex.Pattern;
7 |
8 | /**
9 | *
13 | * @author : Allen
14 | * date : 2018/06/14
15 | * desc : 网络缓存 参考 https://www.jianshu.com/p/cf59500990c7
16 | * version : 1.0
17 | *
18 | */
19 |
20 | public class NetCacheInterceptor implements Interceptor {
21 | @Override
22 | public Response intercept(Chain chain) throws IOException {
23 |
24 | Request request = chain.request();
25 | boolean connected = isNetworkConnected();
26 | if (connected) {
27 | //如果有网络,缓存60s
28 | Response response = chain.proceed(request);
29 | int maxTime = 60;
30 | return response.newBuilder()
31 | .removeHeader("Pragma")
32 | .header("Cache-Control", "public, max-age=" + maxTime)
33 | .build();
34 | }
35 | //如果没有网络,不做处理,直接返回
36 | return chain.proceed(request);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/interceptor/NoNetCacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.interceptor;
2 |
3 | import java.io.IOException;
4 |
5 | import okhttp3.CacheControl;
6 | import okhttp3.Interceptor;
7 | import okhttp3.Request;
8 | import okhttp3.Response;
9 |
10 | import static com.allen.library.utils.NetUtils.isNetworkConnected;
11 |
12 | /**
13 | *
14 | * @author : Allen
15 | * date : 2018/06/14
16 | * desc : 网络缓存 参考 https://www.jianshu.com/p/cf59500990c7
17 | * version : 1.0
18 | *
19 | */
20 |
21 | public class NoNetCacheInterceptor implements Interceptor {
22 | @Override
23 | public Response intercept(Chain chain) throws IOException {
24 |
25 | Request request = chain.request();
26 | boolean connected = isNetworkConnected();
27 | //如果没有网络,则启用 FORCE_CACHE
28 | if (!connected) {
29 | request = request.newBuilder()
30 | .cacheControl(CacheControl.FORCE_CACHE)
31 | .build();
32 |
33 | Response response = chain.proceed(request);
34 |
35 | //没网的时候如果也没缓存的话就走网络
36 | if (response.code() == 504) {
37 | request = request.newBuilder()
38 | .cacheControl(CacheControl.FORCE_NETWORK)
39 | .build();
40 | return chain.proceed(request);
41 | }
42 |
43 | return response.newBuilder()
44 | .header("Cache-Control", "public, only-if-cached, max-stale=3600")
45 | .removeHeader("Pragma")
46 | .build();
47 | }
48 | //有网络的时候,这个拦截器不做处理,直接返回
49 | return chain.proceed(request);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/interceptor/ReceivedCookiesInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.interceptor;
2 |
3 |
4 | import com.allen.library.constant.SPKeys;
5 | import com.allen.library.utils.SPUtils;
6 |
7 | import java.io.IOException;
8 | import java.util.HashSet;
9 |
10 | import okhttp3.Interceptor;
11 | import okhttp3.Response;
12 |
13 | /**
14 | * Created by Allen on 2017/5/11.
15 | *
11 | * @author : Allen
12 | * date : 2018/06/14
13 | * desc : 日志打印格式化处理 https://www.jianshu.com/p/e044cab4f530
14 | * version : 1.0
15 | *
16 | */
17 | public class RxHttpLogger implements HttpLoggingInterceptor.Logger {
18 | private StringBuffer mMessage = new StringBuffer();
19 |
20 | @Override
21 | public void log(String message) {
22 | // 请求或者响应开始
23 | if (message.startsWith("--> POST")) {
24 | mMessage.setLength(0);
25 | mMessage.append(" ");
26 | mMessage.append("\r\n");
27 | }
28 | if (message.startsWith("--> GET")) {
29 | mMessage.setLength(0);
30 | mMessage.append(" ");
31 | mMessage.append("\r\n");
32 | }
33 | // 以{}或者[]形式的说明是响应结果的json数据,需要进行格式化
34 | if ((message.startsWith("{") && message.endsWith("}"))
35 | || (message.startsWith("[") && message.endsWith("]"))) {
36 | message = JsonUtil.formatJson(message);
37 | }
38 | mMessage.append(message.concat("\n"));
39 | // 请求或者响应结束,打印整条日志
40 | if (message.startsWith("<-- END HTTP")) {
41 | Log.e("RxHttpUtils", mMessage.toString());
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/interceptor/Transformer.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.interceptor;
2 |
3 |
4 | import android.app.Dialog;
5 |
6 | import io.reactivex.Observable;
7 | import io.reactivex.ObservableSource;
8 | import io.reactivex.ObservableTransformer;
9 | import io.reactivex.android.schedulers.AndroidSchedulers;
10 | import io.reactivex.annotations.NonNull;
11 | import io.reactivex.disposables.Disposable;
12 | import io.reactivex.functions.Action;
13 | import io.reactivex.functions.Consumer;
14 | import io.reactivex.schedulers.Schedulers;
15 |
16 |
17 | /**
18 | * Created by Allen on 2016/12/20.
19 | *
7 | * @author : Allen
8 | * e-mail : lygttpod@163.com.com
9 | * date : 2018/08/09
10 | * desc : 请求管理接口
11 | * version : 1.0
12 | *
13 | */
14 | public interface IRxHttpManager
12 | * @author : Allen
13 | * date : 2018/06/14
14 | * desc : 管理管理类
15 | * version : 1.0
16 | *
17 | */
18 | public class NetUtils {
19 | /**
20 | * 判断是否有网络
21 | *
22 | * @return 返回值
23 | */
24 | public static boolean isNetworkConnected() {
25 | Context context = RxHttpUtils.getContext();
26 | if (context != null) {
27 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
28 | NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
29 | if (mNetworkInfo != null) {
30 | return mNetworkInfo.isAvailable();
31 | }
32 | }
33 | return false;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/library_net/src/main/java/com/allen/library/utils/ParamUtils.java:
--------------------------------------------------------------------------------
1 | package com.allen.library.utils;
2 |
3 |
4 | import java.util.Map;
5 | import java.util.TreeMap;
6 |
7 | /**
8 | * Created by Allen on 2016/12/8.
9 | *
13 | * @author : xiaoyao
14 | * e-mail : xiaoyao@51vest.com
15 | * date : 2018/07/27
16 | * desc :
17 | * version : 1.0
18 | *
19 | */
20 | public class CommonFragmentAdapter extends FragmentPagerAdapter {
21 |
22 | private List
13 | * @author : xiaoyao
14 | * e-mail : xiaoyao@51vest.com
15 | * date : 2018/07/20
16 | * desc :
17 | * version : 1.0
18 | *
19 | */
20 | public class ErrorFragment extends BaseFragment {
21 | private TextView errorTipTv;
22 |
23 | private String errorMsg;
24 |
25 | public static ErrorFragment newInstance(String errorMsg) {
26 | ErrorFragment fragment = new ErrorFragment();
27 | Bundle bundle = new Bundle();
28 | bundle.putSerializable("MSG", errorMsg);
29 | fragment.setArguments(bundle);
30 | return fragment;
31 | }
32 |
33 | @Override
34 | protected void lazyLoad() {
35 |
36 | }
37 |
38 | @Override
39 | public int bindLayout() {
40 | return R.layout.fragment_error;
41 | }
42 |
43 | @Override
44 | public void initParams() {
45 | errorMsg = getArguments().getString("MSG");
46 | }
47 |
48 | @Override
49 | public void initTopBar(TopBar topBar) {
50 | hideTopBar();
51 | }
52 |
53 | @Override
54 | public void initView(View view) {
55 | errorTipTv = view.findViewById(R.id.error_tip_tv);
56 | }
57 |
58 | @Override
59 | public boolean isCanRefresh() {
60 | return false;
61 | }
62 |
63 | @Override
64 | public void doOnRefresh() {
65 |
66 | }
67 |
68 | @Override
69 | public void doBusiness(Context context) {
70 | errorTipTv.setText(errorMsg);
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/bean/Tab.java:
--------------------------------------------------------------------------------
1 | package com.library.base.bean;
2 |
3 | /**
4 | * Created by Allen on 2017/4/28.
5 | * 封装底部导航数据信息
6 | */
7 | public class Tab {
8 |
9 | private String title;
10 |
11 | private int iconNormalResId;
12 | private int iconPressedResId;
13 |
14 | private int textNormalColor;
15 | private int textSelectColor;
16 |
17 |
18 | public Tab(String title, int iconNormalResId, int iconPressedResId, int textNormalColor, int textSelectColor) {
19 | this.title = title;
20 | this.iconNormalResId = iconNormalResId;
21 | this.iconPressedResId = iconPressedResId;
22 | this.textNormalColor = textNormalColor;
23 | this.textSelectColor = textSelectColor;
24 | }
25 |
26 | public String getTitle() {
27 | return title;
28 | }
29 |
30 | public void setTitle(String title) {
31 | this.title = title;
32 | }
33 |
34 | public int getIconNormalResId() {
35 | return iconNormalResId;
36 | }
37 |
38 | public void setIconNormalResId(int iconNormalResId) {
39 | this.iconNormalResId = iconNormalResId;
40 | }
41 |
42 | public int getIconPressedResId() {
43 | return iconPressedResId;
44 | }
45 |
46 | public void setIconPressedResId(int iconPressedResId) {
47 | this.iconPressedResId = iconPressedResId;
48 | }
49 |
50 | public int getTextNormalColor() {
51 | return textNormalColor;
52 | }
53 |
54 | public void setTextNormalColor(int textNormalColor) {
55 | this.textNormalColor = textNormalColor;
56 | }
57 |
58 | public int getTextSelectColor() {
59 | return textSelectColor;
60 | }
61 |
62 | public void setTextSelectColor(int textSelectColor) {
63 | this.textSelectColor = textSelectColor;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/mvp/BaseMvpActivity.java:
--------------------------------------------------------------------------------
1 | package com.library.base.mvp;
2 |
3 | import android.app.Dialog;
4 |
5 | import com.library.base.base.BaseActivity;
6 |
7 | /**
8 | *
9 | * @author : xiaoyao
10 | * e-mail : xiaoyao@51vest.com
11 | * date : 2018/07/17
12 | * desc : MVP activity 基类
13 | * version : 1.0
14 | *
15 | */
16 | public abstract class BaseMvpActivity
9 | * @author : xiaoyao
10 | * e-mail : xiaoyao@51vest.com
11 | * date : 2018/07/20
12 | * desc : MVP fragment 基类
13 | * version : 1.0
14 | *
15 | */
16 | public abstract class BaseMvpFragment
5 | * @author : xiaoyao
6 | * e-mail : xiaoyao@51vest.com
7 | * date : 2018/07/19
8 | * desc :
9 | * version : 1.0
10 | *
11 | */
12 | public abstract class BaseMvpPresenter
5 | * @author : xiaoyao
6 | * e-mail : xiaoyao@51vest.com
7 | * date : 2018/07/05
8 | * desc :
9 | * version : 1.0
10 | *
11 | */
12 | public interface IBaseMvpPresenter
8 | * @author : xiaoyao
9 | * e-mail : xiaoyao@51vest.com
10 | * date : 2018/07/05
11 | * desc :
12 | * version : 1.0
13 | *
14 | */
15 | public interface IBaseMvpView {
16 |
17 | void showToast(String msg);
18 |
19 | void showLoading();
20 |
21 | void hideLoading();
22 |
23 | Dialog getLoadingDialog();
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/permission/PermissionListener.java:
--------------------------------------------------------------------------------
1 | package com.library.base.permission;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by Allen on 2017/4/18.
7 | * 权限管理回调接口
8 | */
9 |
10 | public interface PermissionListener {
11 |
12 | /**
13 | * 权限已同意
14 | */
15 | void onGranted();
16 |
17 | /**
18 | * 拒绝权限
19 | *
20 | * @param deniedPermission
21 | */
22 | void onDenied(List
10 | * @author : xiaoyao
11 | * e-mail : xiaoyao@51vest.com
12 | * date : 2018/03/14
13 | * desc :
14 | * version : 1.0
15 | *
16 | */
17 |
18 | public class PhoneFormatUtils {
19 |
20 |
21 | /**
22 | * 电话3 4 4格式(即:xxx xxxx xxxx)
23 | * 电话长度11位数字
24 | * @param view 输入框
25 | * @param text 文本
26 | */
27 | public static void onTextChanged344(EditText view, String text) {
28 | if (view== null || text == null || text.length() == 0) return;
29 | char space = ' ';
30 | int indexSpace1 = 3;
31 | int indexSpace2 = 8;
32 | StringBuilder sb = new StringBuilder();
33 | //1.取出所有字符,去掉' '和非法字符
34 | for (int i = 0; i < text.length(); i++) {
35 | //如果数字数大于11位,去掉后面的数字
36 | if(sb.length() >= 11){
37 | break;
38 | }
39 |
40 | //是否合法字符(0~9)
41 | Pattern pattern = Pattern.compile("^[0-9]*$");
42 | Matcher matcher = pattern.matcher(String.valueOf(text.charAt(i)));
43 | if (text.charAt(i) != space && matcher.matches()) {
44 | sb.append(text.charAt(i));
45 | }
46 | }
47 |
48 | //2.根据长度追加' '
49 | if(sb.length() > indexSpace1){
50 | sb.insert(indexSpace1, space);
51 | }
52 | if(sb.length() > indexSpace2){
53 | sb.insert(indexSpace2, space);
54 | }
55 | //3.设置文本和光标位置
56 | if(!sb.toString().equals(text)){
57 | view.setText(sb.toString());
58 | view.setSelection(sb.length());
59 | }
60 | }
61 |
62 | /**
63 | * 获得已输入的电话号,不包括空格
64 | * @param editText 输入控件
65 | * @return 电话号
66 | */
67 | public static String getPhoneNumber(EditText editText){
68 | if (editText== null || editText.getText() == null) return "";
69 | String text = editText.getText().toString();
70 | char space = ' ';
71 | StringBuilder sb = new StringBuilder();
72 | for (int i = 0; i < text.length(); i++) {
73 | if (text.charAt(i) != space) {
74 | sb.append(text.charAt(i));
75 | }
76 | }
77 | return sb.toString();
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/utils/ToastUtils.java:
--------------------------------------------------------------------------------
1 | package com.library.base.utils;
2 |
3 | import android.content.Context;
4 | import android.widget.Toast;
5 |
6 |
7 | /**
8 | * Created by Allen on 2017/10/31.
9 | *
10 | * @author Allen
11 | * Toast工具类
12 | */
13 |
14 | public class ToastUtils {
15 |
16 | private static Toast mToast;
17 |
18 | /**
19 | * Toast提示
20 | *
21 | * @param msg 提示内容
22 | */
23 | public static void showToast(Context context, String msg) {
24 | if (mToast == null) {
25 | mToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
26 | } else {
27 | mToast.setText(msg);
28 | }
29 | mToast.show();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/module_base/src/main/java/com/library/base/view/RVView.java:
--------------------------------------------------------------------------------
1 | package com.library.base.view;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | *
7 | * @author : xiaoyao
8 | * e-mail : xiaoyao@51vest.com
9 | * date : 2018/07/30
10 | * desc :
11 | * version : 1.0
12 | *
13 | */
14 | public interface RVView