├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
└── runConfigurations.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── qyh
│ │ └── androidprojecthelper
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── qyh
│ │ │ └── androidprojecthelper
│ │ │ ├── LuncherActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── adapter
│ │ │ └── FirstTabAdapter.java
│ │ │ ├── api
│ │ │ ├── Api.java
│ │ │ └── ApiService.java
│ │ │ ├── base
│ │ │ ├── AppManager.java
│ │ │ ├── BaseActivity.java
│ │ │ ├── BaseApplication.java
│ │ │ ├── BaseFragment.java
│ │ │ ├── BaseFragmentAdapter.java
│ │ │ ├── BaseFragmentStateAdapter.java
│ │ │ ├── BaseModel.java
│ │ │ ├── BasePresenter.java
│ │ │ ├── BaseView.java
│ │ │ └── baseadapter
│ │ │ │ ├── AlphaInAnimation.java
│ │ │ │ ├── BaseAnimation.java
│ │ │ │ ├── BaseQuickAdapter.java
│ │ │ │ ├── BaseViewHolder.java
│ │ │ │ ├── OnItemClickListener.java
│ │ │ │ ├── ScaleInAnimation.java
│ │ │ │ ├── SimpleClickListener.java
│ │ │ │ ├── SlideInBottomAnimation.java
│ │ │ │ ├── SlideInLeftAnimation.java
│ │ │ │ └── SlideInRightAnimation.java
│ │ │ ├── baserx
│ │ │ ├── RxBus.java
│ │ │ ├── RxCache.java
│ │ │ ├── RxManager.java
│ │ │ ├── RxSchedulers.java
│ │ │ ├── RxSubscriber.java
│ │ │ └── ServerException.java
│ │ │ ├── bean
│ │ │ ├── FirstBean.java
│ │ │ ├── GirlData.java
│ │ │ ├── SecondChannelTabBean.java
│ │ │ └── TabEntity.java
│ │ │ ├── contract
│ │ │ └── FirstContract.java
│ │ │ ├── db
│ │ │ └── SecondChannelManager.java
│ │ │ ├── fragment
│ │ │ ├── FirstTabFragment.java
│ │ │ ├── SecondListFragment.java
│ │ │ ├── SecondTabFragment.java
│ │ │ ├── TestFragment.java
│ │ │ └── ThirdTabFragment.java
│ │ │ ├── launcher
│ │ │ ├── LauncherView.java
│ │ │ ├── Utils.java
│ │ │ ├── ViewPath.java
│ │ │ ├── ViewPathEvaluator.java
│ │ │ └── ViewPoint.java
│ │ │ ├── model
│ │ │ └── FirstModel.java
│ │ │ ├── presenter
│ │ │ └── firstPresenter.java
│ │ │ ├── utils
│ │ │ ├── ACache.java
│ │ │ ├── CollectionUtils.java
│ │ │ ├── GlideRoundTransformUtil.java
│ │ │ ├── ImageLoaderUtils.java
│ │ │ ├── NetWorkUtils.java
│ │ │ ├── TUtil.java
│ │ │ ├── ToastUitl.java
│ │ │ └── Utils.java
│ │ │ └── view
│ │ │ ├── CustomViewPager.java
│ │ │ ├── LoadingDialog.java
│ │ │ ├── bottombar
│ │ │ ├── BottomBar.java
│ │ │ └── BottomBarTab.java
│ │ │ ├── launcher
│ │ │ ├── LauncherView.java
│ │ │ ├── ViewPath.java
│ │ │ ├── ViewPathEvaluator.java
│ │ │ └── ViewPoint.java
│ │ │ └── refresh
│ │ │ ├── NormalRefreshViewHolder.java
│ │ │ ├── RefreshLayout.java
│ │ │ ├── RefreshScrollingUtil.java
│ │ │ ├── RefreshViewHolder.java
│ │ │ └── StickyNavLayout.java
│ └── res
│ │ ├── drawable
│ │ ├── bg_msg_bubble.xml
│ │ ├── loading.xml
│ │ ├── loading_dialog_progressbar.xml
│ │ ├── shape_circle_blue.xml
│ │ ├── shape_circle_purple.xml
│ │ ├── shape_circle_red.xml
│ │ ├── shape_circle_yellow.xml
│ │ └── shape_loading_dialog.xml
│ │ ├── layout
│ │ ├── activity_luncher.xml
│ │ ├── activity_main.xml
│ │ ├── appbar.xml
│ │ ├── def_load_more_failed.xml
│ │ ├── dialog_loading.xml
│ │ ├── fragment_firtst.xml
│ │ ├── fragment_main.xml
│ │ ├── fragment_second.xml
│ │ ├── fragment_second_list.xml
│ │ ├── fragment_test.xml
│ │ ├── item_first.xml
│ │ ├── not_loading.xml
│ │ ├── view_normal_refresh_footer.xml
│ │ ├── view_refresh_header_normal.xml
│ │ └── widget_load_view.xml
│ │ ├── mipmap-hdpi
│ │ ├── bga_refresh_loading01.png
│ │ ├── bga_refresh_loading02.png
│ │ ├── bga_refresh_loading03.png
│ │ ├── bga_refresh_loading04.png
│ │ ├── bga_refresh_loading05.png
│ │ ├── bga_refresh_loading06.png
│ │ ├── bga_refresh_loading07.png
│ │ ├── bga_refresh_loading08.png
│ │ ├── bga_refresh_loading09.png
│ │ ├── bga_refresh_loading10.png
│ │ ├── bga_refresh_loading11.png
│ │ ├── bga_refresh_loading12.png
│ │ ├── ic_launcher.png
│ │ ├── refresh_head_arrow.png
│ │ └── wx_scan_line.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ ├── actionbar_shadow_up.9.png
│ │ ├── ic_empty_picture.png
│ │ ├── ic_image_loading.png
│ │ ├── ic_launcher.png
│ │ ├── loading_progress.png
│ │ ├── logo.jpg
│ │ ├── n_faxian.png
│ │ ├── n_geren.png
│ │ ├── n_shouye.png
│ │ ├── slogan.png
│ │ ├── toux2.png
│ │ ├── y_faxian.png
│ │ ├── y_geren.png
│ │ └── y_shouye.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── array.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── qyh
│ └── androidprojecthelper
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | AndroidProjectHelper
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.8
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 安卓项目快速开发框架
2 |
3 | 终结目标:不重复造轮子,基于此框架可以快速开发出一款APP
4 |
5 | 功能在慢慢完善中。。
6 |
7 | ## 特性
8 | * 1、当前主流框架 MVP + Retrofit + RxJava。
9 | * 2、Activity和Fragment结合MVP模式的完整封装,大大减少代码量。
10 | * 3、酷炫的APP启动动画。
11 | * 4、沉浸式状态栏使用与屏幕适配。
12 | * 5、RxBus进行组件之间通讯,降低耦合度。
13 | * 6、``ToolBar``,``Glide``,多层级Viewpager的使用。
14 | * 7、自定义下拉刷新,上拉加载。
15 |
16 | # 闲话少唠,代码先读为快(核心代码)
17 | **1. View 中代码,泛型中传入P 和m,并绑定彼此之间的关系**
18 | ````java
19 | public class FirstTabFragment extends BaseFragment
20 |
21 | @Override
22 | public void initPresenter() {
23 | mPresenter.setVM(this,mModel);
24 | }
25 | ````
26 | **2. Presenter中代码,观察者模式,model中请求数据后,会回调到presenterz中**
27 | ````java
28 | @Override
29 | public void getFirstListDataRequest(int size, int page) {
30 |
31 | mRxManage.add(mModel.getListData(size,page).subscribe(new RxSubscriber>(mContext,false) {
32 | @Override
33 | public void onStart() {
34 | super.onStart();
35 | mView.showLoading(mContext.getString(R.string.loading));
36 | }
37 | @Override
38 | protected void _onNext(List firstBeen) {
39 | mView.showListData(firstBeen);
40 | mView.stopLoading();
41 | }
42 | @Override
43 | protected void _onError(String message) {
44 | mView.showErrorTip(message);
45 | }
46 | }));
47 | }
48 | ````
49 | **3. Model中代码,主要是就是请求网络,将结果发送到presenterz中**
50 | ````java
51 | @Override
52 | public Observable> getListData(int size, int page) {
53 |
54 | return Api.getInstance().service.getListData(size,page)
55 | .map(new Func1>() {
56 | @Override
57 | public List call(GirlData girlData) {
58 | return girlData.getResults();
59 | }
60 | }).compose(RxSchedulers.>io_main());
61 | }
62 |
63 |
64 | # 主要核心代码就是以上这些,完美的实现请求网络这个过程,通过rxJava观察者机制减少接口的使用,大大减少代码中无用的类!
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | //butterknife
3 | apply plugin: 'android-apt'
4 |
5 | android {
6 | compileSdkVersion 25
7 | buildToolsVersion "25.0.0"
8 |
9 | defaultConfig {
10 | applicationId "qyh.androidprojecthelper"
11 | minSdkVersion 15
12 | targetSdkVersion 25
13 | versionCode 1
14 | versionName "1.0"
15 | //开启分包模式
16 | multiDexEnabled=true
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | }
25 |
26 | dependencies {
27 | compile fileTree(include: ['*.jar'], dir: 'libs')
28 | testCompile 'junit:junit:4.12'
29 | compile 'com.android.support:appcompat-v7:25.0.0'
30 | compile 'com.android.support:multidex:1.0.0'
31 | compile 'com.jakewharton:butterknife:5.1.1'
32 | //屏幕适配
33 | compile 'com.zhy:autolayout:1.4.5'
34 | //retrofit和rxjava
35 | compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
36 | compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
37 | compile 'io.reactivex:rxjava:1.0.1'
38 | compile 'io.reactivex:rxandroid:1.0.1'
39 | compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
40 | compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
41 | compile 'com.android.support:recyclerview-v7:25.0.0'
42 | compile 'cn.yipianfengye.android:zxing-library:2.1'
43 | //view注解
44 | compile 'com.jakewharton:butterknife:8.4.0'
45 | apt 'com.jakewharton:butterknife-compiler:8.4.0'
46 | compile 'com.github.bumptech.glide:glide:3.7.0'
47 | //菜单栏
48 | compile 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.0@aar'
49 | compile 'com.android.support:design:25.0.0'
50 | }
51 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\StudioSDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/qyh/androidprojecthelper/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper;
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 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
14 | android:supportsRtl="true"
15 | android:theme="@style/AppTheme">
16 |
17 |
18 |
19 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/LuncherActivity.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 | import android.widget.Button;
10 |
11 |
12 | /**
13 | * 描述:APP启动页
14 | * Created by qyh on 2016/12/10.
15 | */
16 | public class LuncherActivity extends AppCompatActivity {
17 | @Override
18 | protected void onCreate(@Nullable Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_luncher);
21 |
22 | Button bu_intoapp = (Button) findViewById(R.id.bu_intoapp);
23 | bu_intoapp.setOnClickListener(new View.OnClickListener() {
24 | @Override
25 | public void onClick(View view) {
26 | toMainActivity();
27 | }
28 | });
29 |
30 | new Handler().postDelayed(new Runnable() {
31 | @Override
32 | public void run() {
33 | toMainActivity();
34 | }
35 | }, 4000);
36 | }
37 | private void toMainActivity(){
38 | Intent intent=new Intent(LuncherActivity.this,MainActivity.class);
39 | startActivity(intent);
40 | finish();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/MainActivity.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.FragmentTransaction;
5 |
6 | import com.flyco.tablayout.CommonTabLayout;
7 | import com.flyco.tablayout.listener.CustomTabEntity;
8 | import com.flyco.tablayout.listener.OnTabSelectListener;
9 |
10 | import java.util.ArrayList;
11 |
12 | import butterknife.BindView;
13 |
14 | import qyh.androidprojecthelper.base.BaseActivity;
15 | import qyh.androidprojecthelper.bean.TabEntity;
16 | import qyh.androidprojecthelper.fragment.FirstTabFragment;
17 |
18 | import qyh.androidprojecthelper.fragment.SecondTabFragment;
19 | import qyh.androidprojecthelper.fragment.ThirdTabFragment;
20 |
21 | /**
22 | * ************************************************************************
23 | * ** _oo0oo_ **
24 | * ** o8888888o **
25 | * ** 88" . "88 **
26 | * ** (| -_- |) **
27 | * ** 0\ = /0 **
28 | * ** ___/'---'\___ **
29 | * ** .' \\\| |// '. **
30 | * ** / \\\||| : |||// \\ **
31 | * ** / _ ||||| -:- |||||- \\ **
32 | * ** | | \\\\ - /// | | **
33 | * ** | \_| ''\---/'' |_/ | **
34 | * ** \ .-\__ '-' __/-. / **
35 | * ** ___'. .' /--.--\ '. .'___ **
36 | * ** ."" '< '.___\_<|>_/___.' >' "". **
37 | * ** | | : '- \'.;'\ _ /';.'/ - ' : | | **
38 | * ** \ \ '_. \_ __\ /__ _/ .-' / / **
39 | * ** ====='-.____'.___ \_____/___.-'____.-'===== **
40 | * ** '=---=' **
41 | * ************************************************************************
42 | * ** 佛祖保佑 镇类之宝 **
43 | * ************************************************************************
44 | *
45 | */
46 | public class MainActivity extends BaseActivity {
47 | @BindView(R.id.tab_layout)
48 | CommonTabLayout tabLayout;
49 | private String[] mTitles={"页面1","页面2","页面3"};
50 | private int[] mIconUnselectIds={R.mipmap.n_shouye, R.mipmap.n_faxian,R.mipmap.n_geren};
51 | private int[] mIconSelectIds={R.mipmap.y_shouye, R.mipmap.y_faxian, R.mipmap.y_geren};
52 |
53 | private ArrayList mTabEntities = new ArrayList<>();
54 | private FirstTabFragment firstTabFragment;
55 | private SecondTabFragment secondTabFragment;
56 | private ThirdTabFragment thirdTabFragment;
57 |
58 | @Override
59 | public int getLayoutId() {
60 | return R.layout.activity_main;
61 | }
62 |
63 | @Override
64 | public void initPresenter() {
65 | }
66 |
67 | @Override
68 | public void initView() {
69 | initTab();
70 | }
71 | @Override
72 | public void onCreate(Bundle savedInstanceState) {
73 | super.onCreate(savedInstanceState);
74 | initFragment(savedInstanceState);
75 | }
76 | private void initTab() {
77 | for (int i = 0; i < mTitles.length; i++) {
78 | mTabEntities.add(new TabEntity(mTitles[i], mIconSelectIds[i], mIconUnselectIds[i]));
79 | }
80 |
81 | tabLayout.setTabData(mTabEntities);
82 | //点击监听
83 | tabLayout.setOnTabSelectListener(new OnTabSelectListener() {
84 | @Override
85 | public void onTabSelect(int position) {
86 | SwitchTo(position);
87 | }
88 | @Override
89 | public void onTabReselect(int position) {
90 | }
91 | });
92 | }
93 | //初始化碎片
94 | private void initFragment(Bundle savedInstanceState) {
95 | FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
96 | int currentTabPosition=0;
97 | if(null==savedInstanceState){
98 | firstTabFragment = new FirstTabFragment();
99 | secondTabFragment = new SecondTabFragment();
100 | thirdTabFragment = new ThirdTabFragment();
101 |
102 | fragmentTransaction.add(R.id.fl_body,firstTabFragment,"firstTabFragment");
103 | fragmentTransaction.add(R.id.fl_body,secondTabFragment,"secondTabFragment");
104 | fragmentTransaction.add(R.id.fl_body,thirdTabFragment,"thirdTabFragment");
105 | }else{
106 | firstTabFragment= (FirstTabFragment) getSupportFragmentManager().findFragmentByTag("firstTabFragment");
107 | secondTabFragment= (SecondTabFragment) getSupportFragmentManager().findFragmentByTag("secondTabFragment");
108 | thirdTabFragment= (ThirdTabFragment) getSupportFragmentManager().findFragmentByTag("thirdTabFragment");
109 | }
110 | fragmentTransaction.commit();
111 | SwitchTo(currentTabPosition);
112 | tabLayout.setCurrentTab(currentTabPosition);
113 | }
114 | private void SwitchTo(int position) {
115 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
116 |
117 | switch (position){
118 | case 0:
119 | transaction.show(firstTabFragment);
120 | transaction.hide(secondTabFragment);
121 | transaction.hide(thirdTabFragment);
122 | transaction.commitAllowingStateLoss();
123 | break;
124 | case 1:
125 | transaction.show(secondTabFragment);
126 | transaction.hide(firstTabFragment);
127 | transaction.hide(thirdTabFragment);
128 | transaction.commitAllowingStateLoss();
129 | break;
130 | case 2:
131 | transaction.show(thirdTabFragment);
132 | transaction.hide(secondTabFragment);
133 | transaction.hide(firstTabFragment);
134 | transaction.commitAllowingStateLoss();
135 | break;
136 | }
137 | }
138 |
139 | @Override
140 | protected void onResume() {
141 | super.onResume();
142 | //1 显示tabLayout的角标 显示未读数
143 | tabLayout.showMsg(1,88);
144 | tabLayout.setMsgMargin(3,0,10);
145 | //隐藏消息
146 | //tabLayout.hideMsg(1);
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/adapter/FirstTabAdapter.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.adapter;
2 |
3 |
4 |
5 | import android.widget.ImageView;
6 |
7 | import java.util.List;
8 |
9 | import qyh.androidprojecthelper.R;
10 | import qyh.androidprojecthelper.base.baseadapter.BaseQuickAdapter;
11 | import qyh.androidprojecthelper.base.baseadapter.BaseViewHolder;
12 | import qyh.androidprojecthelper.bean.FirstBean;
13 | import qyh.androidprojecthelper.utils.ImageLoaderUtils;
14 |
15 | /**
16 | * 描述:
17 | * Created by qyh on 2016/12/30.
18 | */
19 | public class FirstTabAdapter extends BaseQuickAdapter {
20 |
21 | public FirstTabAdapter(int layoutResId, List listData) {
22 | super(layoutResId, listData);
23 | }
24 |
25 | @Override
26 | protected void convert(BaseViewHolder helper, Object item, int position) {
27 | FirstBean data=(FirstBean)item;
28 | ImageLoaderUtils.display(mContext,(ImageView) helper.getView(R.id.iv_item_picture)
29 | ,data.getUrl());
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/api/Api.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.api;
2 |
3 |
4 | import android.util.Log;
5 |
6 | import com.google.gson.Gson;
7 | import com.google.gson.GsonBuilder;
8 |
9 | import java.io.File;
10 | import java.io.IOException;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | import okhttp3.Cache;
14 | import okhttp3.CacheControl;
15 | import okhttp3.Interceptor;
16 | import okhttp3.OkHttpClient;
17 | import okhttp3.Request;
18 | import okhttp3.Response;
19 | import okhttp3.logging.HttpLoggingInterceptor;
20 | import qyh.androidprojecthelper.base.BaseApplication;
21 | import qyh.androidprojecthelper.utils.NetWorkUtils;
22 | import retrofit2.Retrofit;
23 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
24 | import retrofit2.converter.gson.GsonConverterFactory;
25 |
26 | /**
27 | * 描述:
28 | * Created by qyh on 2016/12/28.
29 | */
30 | public class Api {
31 | public Retrofit retrofit;
32 | public ApiService service;
33 |
34 | private static class SingletonHolder {
35 | private static final Api INSTANCE = new Api();
36 | }
37 |
38 | public static Api getInstance() {
39 | return SingletonHolder.INSTANCE;
40 | }
41 |
42 | //增加头部信息
43 | Interceptor headerInterceptor =new Interceptor() {
44 | @Override
45 | public Response intercept(Chain chain) throws IOException {
46 | Request build = chain.request().newBuilder()
47 | .addHeader("Content-Type", "application/json")
48 | .build();
49 | return chain.proceed(build);
50 | }
51 | };
52 |
53 | //构造方法私有
54 | private Api() {
55 | HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
56 | interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
57 |
58 | File cacheFile = new File(BaseApplication.getAppContext().getCacheDir(), "cache");
59 | Cache cache = new Cache(cacheFile, 1024 * 1024 * 100); //100Mb
60 |
61 | OkHttpClient okHttpClient = new OkHttpClient.Builder()
62 | .readTimeout(7676, TimeUnit.MILLISECONDS)
63 | .connectTimeout(7676, TimeUnit.MILLISECONDS)
64 | .addInterceptor(headerInterceptor)
65 | .addInterceptor(interceptor)
66 | .addNetworkInterceptor(new HttpCacheInterceptor())
67 | .cache(cache)
68 | .build();
69 |
70 | Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").serializeNulls().create();
71 |
72 | retrofit = new Retrofit.Builder()
73 | .client(okHttpClient)
74 | .addConverterFactory(GsonConverterFactory.create(gson))
75 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
76 | .baseUrl("http://gank.io/api/")
77 | .build();
78 | service = retrofit.create(ApiService.class);
79 | }
80 |
81 | class HttpCacheInterceptor implements Interceptor {
82 |
83 | @Override
84 | public Response intercept(Chain chain) throws IOException {
85 | Request request = chain.request();
86 | if (!NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) {
87 | request = request.newBuilder()
88 | .cacheControl(CacheControl.FORCE_CACHE)
89 | .build();
90 | Log.d("Okhttp", "no network");
91 | }
92 |
93 | Response originalResponse = chain.proceed(request);
94 | if (NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) {
95 | //有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置
96 | String cacheControl = request.cacheControl().toString();
97 | return originalResponse.newBuilder()
98 | .header("Cache-Control", cacheControl)
99 | .removeHeader("Pragma")
100 | .build();
101 | } else {
102 | return originalResponse.newBuilder()
103 | .header("Cache-Control", "public, only-if-cached, max-stale=2419200")
104 | .removeHeader("Pragma")
105 | .build();
106 | }
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/api/ApiService.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.api;
2 |
3 | import qyh.androidprojecthelper.bean.GirlData;
4 |
5 | import retrofit2.http.GET;
6 |
7 | import retrofit2.http.Path;
8 | import rx.Observable;
9 |
10 | /**
11 | * 描述:
12 | * Created by qyh on 2016/12/28.
13 | */
14 | public interface ApiService {
15 | /**
16 | * 图片URL http://gank.io/api/data/福利/20/1
17 | * @param size
18 | * @param page
19 | * @return
20 | */
21 | @GET("data/福利/{size}/{page}")
22 | Observable getListData(
23 | // @Header("Cache-Control") String cacheControl,
24 | @Path("size") int size,
25 | @Path("page") int page);
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/AppManager.java:
--------------------------------------------------------------------------------
1 |
2 | package qyh.androidprojecthelper.base;
3 |
4 | import android.app.Activity;
5 | import android.app.ActivityManager;
6 | import android.content.Context;
7 |
8 | import java.util.Stack;
9 |
10 | /**
11 | * activity管理
12 | * Created by qyh on 2016/12/7.
13 | */
14 | public class AppManager {
15 | private static Stack activityStack;
16 | private volatile static AppManager instance;
17 |
18 | private AppManager() {
19 |
20 | }
21 | /**
22 | * 单一实例
23 | */
24 | public static AppManager getAppManager() {
25 | if (instance == null) {
26 | synchronized (AppManager.class){
27 | if(instance==null){
28 | instance = new AppManager();
29 | instance.activityStack = new Stack();
30 | }
31 | }
32 |
33 | }
34 | return instance;
35 | }
36 |
37 | /**
38 | * 添加Activity到堆栈
39 | */
40 | public void addActivity(Activity activity) {
41 | if (activityStack == null) {
42 | activityStack = new Stack();
43 | }
44 | activityStack.add(activity);
45 | }
46 |
47 | /**
48 | * 获取当前Activity(堆栈中最后一个压入的)
49 | */
50 | public Activity currentActivity() {
51 | try {
52 | Activity activity = activityStack.lastElement();
53 | return activity;
54 | } catch (Exception e) {
55 | // e.printStackTrace();
56 | return null;
57 | }
58 | }
59 |
60 | /**
61 | * 获取当前Activity的前一个Activity
62 | */
63 | public Activity preActivity() {
64 | int index = activityStack.size() - 2;
65 | if (index < 0) {
66 | return null;
67 | }
68 | Activity activity = activityStack.get(index);
69 | return activity;
70 | }
71 |
72 | /**
73 | * 结束当前Activity(堆栈中最后一个压入的)
74 | */
75 | public void finishActivity() {
76 | Activity activity = activityStack.lastElement();
77 | finishActivity(activity);
78 | }
79 |
80 | /**
81 | * 结束指定的Activity
82 | */
83 | public void finishActivity(Activity activity) {
84 | if (activity != null) {
85 | activityStack.remove(activity);
86 | activity.finish();
87 | activity = null;
88 | }
89 | }
90 |
91 | /**
92 | * 移除指定的Activity
93 | */
94 | public void removeActivity(Activity activity) {
95 | if (activity != null) {
96 | activityStack.remove(activity);
97 | activity = null;
98 | }
99 | }
100 |
101 | /**
102 | * 结束指定类名的Activity
103 | */
104 | public void finishActivity(Class> cls) {
105 | try {
106 | for (Activity activity : activityStack) {
107 | if (activity.getClass().equals(cls)) {
108 | finishActivity(activity);
109 | }
110 | }
111 | } catch (Exception e) {
112 | e.printStackTrace();
113 | }
114 |
115 | }
116 |
117 | /**
118 | * 结束所有Activity
119 | */
120 | public void finishAllActivity() {
121 | for (int i = 0, size = activityStack.size(); i < size; i++) {
122 | if (null != activityStack.get(i)) {
123 | activityStack.get(i).finish();
124 | }
125 | }
126 | activityStack.clear();
127 | }
128 |
129 | /**
130 | * 返回到指定的activity
131 | *
132 | * @param cls
133 | */
134 | public void returnToActivity(Class> cls) {
135 | while (activityStack.size() != 0)
136 | if (activityStack.peek().getClass() == cls) {
137 | break;
138 | } else {
139 | finishActivity(activityStack.peek());
140 | }
141 | }
142 |
143 |
144 | /**
145 | * 是否已经打开指定的activity
146 | * @param cls
147 | * @return
148 | */
149 | public boolean isOpenActivity(Class> cls) {
150 | if (activityStack!=null){
151 | for (int i = 0, size = activityStack.size(); i < size; i++) {
152 | if (cls == activityStack.peek().getClass()) {
153 | return true;
154 | }
155 | }
156 | }
157 | return false;
158 | }
159 |
160 | /**
161 | * 退出应用程序
162 | *
163 | * @param context 上下文
164 | * @param isBackground 是否开开启后台运行
165 | */
166 | public void AppExit(Context context, Boolean isBackground) {
167 | try {
168 | finishAllActivity();
169 | ActivityManager activityMgr = (ActivityManager) context
170 | .getSystemService(Context.ACTIVITY_SERVICE);
171 | activityMgr.restartPackage(context.getPackageName());
172 | } catch (Exception e) {
173 |
174 | } finally {
175 | // 注意,如果您有后台程序运行,请不要支持此句子
176 | if (!isBackground) {
177 | System.exit(0);
178 | }
179 | }
180 | }
181 | }
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.pm.ActivityInfo;
7 | import android.os.Bundle;
8 | import android.view.Window;
9 |
10 |
11 | import com.zhy.autolayout.AutoLayoutActivity;
12 |
13 | import butterknife.ButterKnife;
14 |
15 | import qyh.androidprojecthelper.baserx.RxManager;
16 | import qyh.androidprojecthelper.utils.TUtil;
17 | import qyh.androidprojecthelper.utils.ToastUitl;
18 | import qyh.androidprojecthelper.view.LoadingDialog;
19 |
20 | /**
21 | * 基类
22 | * AutoLayoutActivity 屏幕适配 详细用法请看https://github.com/hongyangAndroid/AndroidAutoLayout
23 | * Created by qyh on 2016/12/7.
24 | */
25 |
26 | /***************使用例子*********************/
27 | //1.mvp模式
28 | //public class SampleActivity extends BaseActivityimplements NewsChannelContract.View {
29 | // @Override
30 | // public int getLayoutId() {
31 | // return R.layout.activity_news_channel;
32 | // }
33 | //
34 | // @Override
35 | // public void initPresenter() {
36 | // mPresenter.setVM(this, mModel);
37 | // }
38 | //
39 | // @Override
40 | // public void initView() {
41 | // }
42 | //}
43 | //2.普通模式
44 | //public class SampleActivity extends BaseActivity {
45 | // @Override
46 | // public int getLayoutId() {
47 | // return R.layout.activity_news_channel;
48 | // }
49 | //
50 | // @Override
51 | // public void initPresenter() {
52 | // }
53 | //
54 | // @Override
55 | // public void initView() {
56 | // }
57 | //}
58 | public abstract class BaseActivity extends AutoLayoutActivity {
59 | public T mPresenter;
60 | public E mModel;
61 | public Context mContext;
62 | public RxManager mRxManager;
63 |
64 | @Override
65 | public void onCreate(Bundle savedInstanceState) {
66 | super.onCreate(savedInstanceState);
67 | mRxManager=new RxManager();
68 | doBeforeSetcontentView();
69 | setContentView(getLayoutId());
70 | ButterKnife.bind(this);
71 | mContext = this;
72 | mPresenter = TUtil.getT(this, 0);
73 | mModel= TUtil.getT(this,1);
74 | if(mPresenter!=null){
75 | mPresenter.mContext=this;
76 | }
77 | this.initPresenter();
78 | this.initView();
79 | }
80 |
81 | /**
82 | * 设置layout前配置
83 | */
84 | private void doBeforeSetcontentView() {
85 |
86 | // 把actvity放到application栈中管理
87 | AppManager.getAppManager().addActivity(this);
88 | // 无标题
89 | requestWindowFeature(Window.FEATURE_NO_TITLE);
90 | // 设置竖屏
91 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
92 | }
93 | /*********************子类实现*****************************/
94 | //获取布局文件
95 | public abstract int getLayoutId();
96 | //简单页面无需mvp就不用管此方法即可,完美兼容各种实际场景的变通
97 | public abstract void initPresenter();
98 | //初始化view
99 | public abstract void initView();
100 |
101 | /**
102 | * 通过Class跳转界面
103 | **/
104 | public void startActivity(Class> cls) {
105 | startActivity(cls, null);
106 | }
107 |
108 | /**
109 | * 通过Class跳转界面
110 | **/
111 | public void startActivityForResult(Class> cls, int requestCode) {
112 | startActivityForResult(cls, null, requestCode);
113 | }
114 |
115 | /**
116 | * 含有Bundle通过Class跳转界面
117 | **/
118 | public void startActivityForResult(Class> cls, Bundle bundle,
119 | int requestCode) {
120 | Intent intent = new Intent();
121 | intent.setClass(this, cls);
122 | if (bundle != null) {
123 | intent.putExtras(bundle);
124 | }
125 | startActivityForResult(intent, requestCode);
126 | }
127 |
128 | /**
129 | * 含有Bundle通过Class跳转界面
130 | **/
131 | public void startActivity(Class> cls, Bundle bundle) {
132 | Intent intent = new Intent();
133 | intent.setClass(this, cls);
134 | if (bundle != null) {
135 | intent.putExtras(bundle);
136 | }
137 | startActivity(intent);
138 | }
139 |
140 | /**
141 | * 开启浮动加载进度条
142 | */
143 | public void startProgressDialog() {
144 | LoadingDialog.showDialogForLoading(this);
145 | }
146 |
147 | /**
148 | * 开启浮动加载进度条
149 | *
150 | * @param msg
151 | */
152 | public void startProgressDialog(String msg) {
153 | LoadingDialog.showDialogForLoading(this, msg, true);
154 | }
155 |
156 | /**
157 | * 停止浮动加载进度条
158 | */
159 | public void stopProgressDialog() {
160 | LoadingDialog.cancelDialogForLoading();
161 | }
162 |
163 | /**
164 | * 短暂显示Toast提示(来自String)
165 | **/
166 | public void showShortToast(String text) {
167 | ToastUitl.showShort(text);
168 | }
169 |
170 | /**
171 | * 短暂显示Toast提示(id)
172 | **/
173 | public void showShortToast(int resId) {
174 | ToastUitl.showShort(resId);
175 | }
176 |
177 | /**
178 | * 长时间显示Toast提示(来自res)
179 | **/
180 | public void showLongToast(int resId) {
181 | ToastUitl.showLong(resId);
182 | }
183 |
184 | /**
185 | * 长时间显示Toast提示(来自String)
186 | **/
187 | public void showLongToast(String text) {
188 | ToastUitl.showLong(text);
189 | }
190 | /**
191 | // * 网络访问错误提醒
192 | // */
193 | // public void showNetErrorTip() {
194 | // ToastUitl.showToastWithImg(getText(R.string.net_error).toString(),R.drawable.ic_wifi_off);
195 | // }
196 | // public void showNetErrorTip(String error) {
197 | // ToastUitl.showToastWithImg(error,R.drawable.ic_wifi_off);
198 | // }
199 | @Override
200 | protected void onResume() {
201 | super.onResume();
202 | //防统计之类的
203 | }
204 |
205 | @Override
206 | protected void onPause() {
207 | super.onPause();
208 |
209 | }
210 |
211 |
212 | @Override
213 | protected void onDestroy() {
214 | super.onDestroy();
215 | if (mPresenter != null)
216 | mPresenter.onDestroy();
217 | mRxManager.clear();
218 | // ButterKnife.unbind(this);
219 | AppManager.getAppManager().finishActivity(this);
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 |
3 |
4 | import android.content.Context;
5 | import android.support.multidex.MultiDexApplication;
6 |
7 | import com.uuzuche.lib_zxing.activity.ZXingLibrary;
8 | import com.zhy.autolayout.config.AutoLayoutConifg;
9 |
10 | /**
11 | * 描述:MultiDexApplication防止方法数过多
12 | * Created by qyh on 2016/12/6.
13 | */
14 | public class BaseApplication extends MultiDexApplication {
15 | private static BaseApplication baseApplication;
16 | @Override
17 | public void onCreate() {
18 | super.onCreate();
19 | baseApplication = this;
20 | //屏幕适配
21 | AutoLayoutConifg.getInstance().useDeviceSize();
22 | ZXingLibrary.initDisplayOpinion(this);
23 | }
24 | public static Context getAppContext() {
25 | return baseApplication;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 |
12 |
13 | import butterknife.ButterKnife;
14 | import qyh.androidprojecthelper.baserx.RxManager;
15 | import qyh.androidprojecthelper.utils.TUtil;
16 | import qyh.androidprojecthelper.utils.ToastUitl;
17 | import qyh.androidprojecthelper.view.LoadingDialog;
18 |
19 | /**
20 | * des:基类fragment
21 | * Created by qyh on 2016/12/7.
22 | */
23 |
24 | /***************使用例子*********************/
25 | //1.mvp模式
26 | //public class SampleFragment extends BaseFragmentimplements NewsChannelContract.View {
27 | // @Override
28 | // public int getLayoutId() {
29 | // return R.layout.activity_news_channel;
30 | // }
31 | //
32 | // @Override
33 | // public void initPresenter() {
34 | // mPresenter.setVM(this, mModel);
35 | // }
36 | //
37 | // @Override
38 | // public void initView() {
39 | // }
40 | //}
41 | //2.普通模式
42 | //public class SampleFragment extends BaseFragment {
43 | // @Override
44 | // public int getLayoutResource() {
45 | // return R.layout.activity_news_channel;
46 | // }
47 | //
48 | // @Override
49 | // public void initPresenter() {
50 | // }
51 | //
52 | // @Override
53 | // public void initView() {
54 | // }
55 | //}
56 | public abstract class BaseFragment extends Fragment {
57 | protected View rootView;
58 | public T mPresenter;
59 | public E mModel;
60 | public RxManager mRxManager;
61 |
62 | @Nullable
63 | @Override
64 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
65 | if (rootView == null)
66 | rootView = inflater.inflate(getLayoutResource(), container, false);
67 | mRxManager=new RxManager();
68 | ButterKnife.bind(this, rootView);
69 | mPresenter = TUtil.getT(this, 0);
70 | mModel= TUtil.getT(this,1);
71 | if(mPresenter!=null){
72 | mPresenter.mContext=this.getActivity();
73 | }
74 | initPresenter();
75 | initView();
76 | return rootView;
77 | }
78 | //获取布局文件
79 | protected abstract int getLayoutResource();
80 | //简单页面无需mvp就不用管此方法即可,完美兼容各种实际场景的变通
81 | public abstract void initPresenter();
82 | //初始化view
83 | protected abstract void initView();
84 |
85 |
86 | /**
87 | * 通过Class跳转界面
88 | **/
89 | public void startActivity(Class> cls) {
90 | startActivity(cls, null);
91 | }
92 |
93 | /**
94 | * 通过Class跳转界面
95 | **/
96 | public void startActivityForResult(Class> cls, int requestCode) {
97 | startActivityForResult(cls, null, requestCode);
98 | }
99 |
100 | /**
101 | * 含有Bundle通过Class跳转界面
102 | **/
103 | public void startActivityForResult(Class> cls, Bundle bundle,
104 | int requestCode) {
105 | Intent intent = new Intent();
106 | intent.setClass(getActivity(), cls);
107 | if (bundle != null) {
108 | intent.putExtras(bundle);
109 | }
110 | startActivityForResult(intent, requestCode);
111 | }
112 |
113 | /**
114 | * 含有Bundle通过Class跳转界面
115 | **/
116 | public void startActivity(Class> cls, Bundle bundle) {
117 | Intent intent = new Intent();
118 | intent.setClass(getActivity(), cls);
119 | if (bundle != null) {
120 | intent.putExtras(bundle);
121 | }
122 | startActivity(intent);
123 | }
124 |
125 |
126 |
127 | /**
128 | * 开启加载进度条
129 | */
130 | public void startProgressDialog() {
131 | LoadingDialog.showDialogForLoading(getActivity());
132 | }
133 |
134 | /**
135 | * 开启加载进度条
136 | *
137 | * @param msg
138 | */
139 | public void startProgressDialog(String msg) {
140 | LoadingDialog.showDialogForLoading(getActivity(), msg, true);
141 | }
142 |
143 | /**
144 | * 停止加载进度条
145 | */
146 | public void stopProgressDialog() {
147 | LoadingDialog.cancelDialogForLoading();
148 | }
149 |
150 |
151 | /**
152 | * 短暂显示Toast提示(来自String)
153 | **/
154 | public void showShortToast(String text) {
155 | ToastUitl.showShort(text);
156 | }
157 |
158 | /**
159 | * 短暂显示Toast提示(id)
160 | **/
161 | public void showShortToast(int resId) {
162 | ToastUitl.showShort(resId);
163 | }
164 |
165 | /**
166 | * 长时间显示Toast提示(来自res)
167 | **/
168 | public void showLongToast(int resId) {
169 | ToastUitl.showLong(resId);
170 | }
171 |
172 | /**
173 | * 长时间显示Toast提示(来自String)
174 | **/
175 | public void showLongToast(String text) {
176 | ToastUitl.showLong(text);
177 | }
178 |
179 |
180 |
181 | // /**
182 | // * 网络访问错误提醒
183 | // */
184 | // public void showNetErrorTip() {
185 | // ToastUitl.showToastWithImg(getText(R.string.net_error).toString(),R.drawable.ic_wifi_off);
186 | // }
187 | //
188 | // public void showNetErrorTip(String error) {
189 | // ToastUitl.showToastWithImg(error,R.drawable.ic_wifi_off);
190 | // }
191 |
192 | @Override
193 | public void onDestroyView() {
194 | super.onDestroyView();
195 | // ButterKnife.unbind(this);
196 | if (mPresenter != null)
197 | mPresenter.onDestroy();
198 | mRxManager.clear();
199 | }
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BaseFragmentAdapter.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 | import android.support.v4.app.FragmentTransaction;
7 |
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | import qyh.androidprojecthelper.utils.CollectionUtils;
13 |
14 | /**
15 | * 该类内的每一个生成的 Fragment 都将保存在内存之中,
16 | * 因此适用于那些相对静态的页,数量也比较少的那种;
17 | * 如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,
18 | * 应该使用FragmentStatePagerAdapter。
19 | */
20 | public class BaseFragmentAdapter extends FragmentPagerAdapter {
21 |
22 | List fragmentList = new ArrayList();
23 | private List mTitles;
24 |
25 | public BaseFragmentAdapter(FragmentManager fm, List fragmentList) {
26 | super(fm);
27 | this.fragmentList = fragmentList;
28 | }
29 |
30 | public BaseFragmentAdapter(FragmentManager fm, List fragmentList, List mTitles) {
31 | super(fm);
32 | this.mTitles = mTitles;
33 | setFragments(fm,fragmentList,mTitles);
34 | }
35 | //刷新fragment
36 | public void setFragments(FragmentManager fm, List fragments, List mTitles) {
37 | this.mTitles = mTitles;
38 | if (this.fragmentList != null) {
39 | FragmentTransaction ft = fm.beginTransaction();
40 | for (Fragment f : this.fragmentList) {
41 | ft.remove(f);
42 | }
43 | ft.commitAllowingStateLoss();
44 | ft = null;
45 | fm.executePendingTransactions();
46 | }
47 | this.fragmentList = fragments;
48 | notifyDataSetChanged();
49 | }
50 |
51 | @Override
52 | public CharSequence getPageTitle(int position) {
53 | return !CollectionUtils.isNullOrEmpty(mTitles) ? mTitles.get(position) : "";
54 | }
55 |
56 | @Override
57 | public Fragment getItem(int position) {
58 | return fragmentList.get(position);
59 | }
60 |
61 | @Override
62 | public int getCount() {
63 | return fragmentList.size();
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BaseFragmentStateAdapter.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentStatePagerAdapter;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import qyh.androidprojecthelper.utils.CollectionUtils;
11 |
12 | /**
13 | * FragmentStatePagerAdapter 和前面的 FragmentPagerAdapter 一样,是继承子 PagerAdapter。
14 | * 但和 FragmentPagerAdapter 不一样的是,
15 | * 正如其类名中的 'State' 所表明的含义一样,
16 | * 该 PagerAdapter 的实现将只保留当前页面,
17 | * 当页面离开视线后,就会被消除,释放其资源;
18 | * 而在页面需要显示时,生成新的页面(就像 ListView 的实现一样)。
19 | * 这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存。
20 | */
21 | public class BaseFragmentStateAdapter extends FragmentStatePagerAdapter {
22 |
23 | List fragmentList = new ArrayList();
24 | private List mTitles;
25 |
26 | public BaseFragmentStateAdapter(FragmentManager fm, List fragmentList) {
27 | super(fm);
28 | this.fragmentList = fragmentList;
29 | }
30 |
31 | public BaseFragmentStateAdapter(FragmentManager fm, List fragmentList, List mTitles) {
32 | super(fm);
33 | this.mTitles = mTitles;
34 | this.fragmentList = fragmentList;
35 | }
36 | @Override
37 | public CharSequence getPageTitle(int position) {
38 | return !CollectionUtils.isNullOrEmpty(mTitles) ? mTitles.get(position) : "";
39 | }
40 |
41 | @Override
42 | public Fragment getItem(int position) {
43 | return fragmentList.get(position);
44 | }
45 |
46 | @Override
47 | public int getCount() {
48 | return fragmentList.size();
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BaseModel.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 |
3 | public interface BaseModel {
4 | }
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 |
3 | import android.content.Context;
4 |
5 | import qyh.androidprojecthelper.baserx.RxManager;
6 |
7 |
8 | /**
9 | * 描述:基类presenter
10 | * Created by qyh on 2016/12/6.
11 | */
12 | public abstract class BasePresenter{
13 | public Context mContext;
14 | public E mModel;
15 | public T mView;
16 | public RxManager mRxManage = new RxManager();
17 |
18 | public void setVM(T v, E m) {
19 | this.mView = v;
20 | this.mModel = m;
21 | this.onStart();
22 | }
23 | public void onStart(){
24 | };
25 | public void onDestroy() {
26 | mRxManage.clear();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/BaseView.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base;
2 | /**
3 | * 描述:
4 | * Created by qyh on 2016/12/28.
5 | */
6 | public interface BaseView {
7 | /*******内嵌加载*******/
8 | void showLoading(String title);
9 | void stopLoading();
10 | void showErrorTip(String msg);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/AlphaInAnimation.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.view.View;
6 |
7 |
8 | public class AlphaInAnimation implements BaseAnimation {
9 |
10 | private static final float DEFAULT_ALPHA_FROM = 0f;
11 | private final float mFrom;
12 |
13 | public AlphaInAnimation() {
14 | this(DEFAULT_ALPHA_FROM);
15 | }
16 |
17 | public AlphaInAnimation(float from) {
18 | mFrom = from;
19 | }
20 |
21 | @Override
22 | public Animator[] getAnimators(View view) {
23 | return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f)};
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/BaseAnimation.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.animation.Animator;
4 | import android.view.View;
5 |
6 |
7 | public interface BaseAnimation {
8 |
9 | Animator[] getAnimators(View view);
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/OnItemClickListener.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.view.View;
4 |
5 |
6 | public abstract class OnItemClickListener extends SimpleClickListener {
7 |
8 |
9 | @Override
10 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
11 | SimpleOnItemClick(adapter,view,position);
12 | }
13 |
14 | @Override
15 | public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
16 |
17 | }
18 |
19 | @Override
20 | public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
21 |
22 | }
23 |
24 | @Override
25 | public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
26 |
27 | }
28 | public abstract void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position);
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/ScaleInAnimation.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.view.View;
6 |
7 | import qyh.androidprojecthelper.base.baseadapter.BaseAnimation;
8 |
9 |
10 | public class ScaleInAnimation implements BaseAnimation {
11 |
12 | private static final float DEFAULT_SCALE_FROM = .5f;
13 | private final float mFrom;
14 |
15 | public ScaleInAnimation() {
16 | this(DEFAULT_SCALE_FROM);
17 | }
18 |
19 | public ScaleInAnimation(float from) {
20 | mFrom = from;
21 | }
22 |
23 | @Override
24 | public Animator[] getAnimators(View view) {
25 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f);
26 | ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f);
27 | return new ObjectAnimator[] { scaleX, scaleY };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/SimpleClickListener.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.support.v4.view.GestureDetectorCompat;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.util.Log;
6 | import android.view.GestureDetector;
7 | import android.view.MotionEvent;
8 | import android.view.View;
9 |
10 | import java.util.Iterator;
11 | import java.util.Set;
12 |
13 |
14 |
15 | public abstract class SimpleClickListener implements RecyclerView.OnItemTouchListener {
16 | private GestureDetectorCompat mGestureDetector;
17 | private RecyclerView recyclerView;
18 | private Set childClickViewIds;
19 | private Set longClickViewIds;
20 | protected BaseQuickAdapter baseQuickAdapter;
21 | public static String TAG = "SimpleClickListener";
22 | private boolean mIsPrepressed = false;
23 | private boolean mIsShowPress = false;
24 | private View mPressedView = null;
25 |
26 | @Override
27 | public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
28 |
29 | if (recyclerView == null) {
30 | this.recyclerView = rv;
31 | this.baseQuickAdapter = (BaseQuickAdapter) recyclerView.getAdapter();
32 | mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener(recyclerView));
33 | }
34 | if (!mGestureDetector.onTouchEvent(e) && e.getActionMasked() == MotionEvent.ACTION_UP && mIsShowPress) {
35 | if (mPressedView!=null){
36 | mPressedView.setPressed(false);
37 | mPressedView = null;
38 | }
39 | mIsShowPress = false;
40 | mIsPrepressed = false;
41 |
42 |
43 | }
44 | return false;
45 | }
46 |
47 | @Override
48 | public void onTouchEvent(RecyclerView rv, MotionEvent e) {
49 | Log.e(TAG, "onTouchEvent: ");
50 | mGestureDetector.onTouchEvent(e);
51 | }
52 |
53 | @Override
54 | public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
55 | }
56 |
57 | private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
58 |
59 | private RecyclerView recyclerView;
60 |
61 | @Override
62 | public boolean onDown(MotionEvent e) {
63 | mIsPrepressed = true;
64 | mPressedView = recyclerView.findChildViewUnder(e.getX(), e.getY());
65 | super.onDown(e);
66 | return false;
67 | }
68 |
69 | @Override
70 | public void onShowPress(MotionEvent e) {
71 | if (mIsPrepressed && mPressedView != null) {
72 | mPressedView.setPressed(true);
73 | mIsShowPress = true;
74 | }
75 | super.onShowPress(e);
76 | }
77 |
78 | public ItemTouchHelperGestureListener(RecyclerView recyclerView) {
79 | this.recyclerView = recyclerView;
80 | }
81 |
82 | @Override
83 | public boolean onSingleTapUp(MotionEvent e) {
84 | if (mIsPrepressed && mPressedView != null) {
85 | mPressedView.setPressed(true);
86 | final View pressedView = mPressedView;
87 | BaseViewHolder vh = (BaseViewHolder) recyclerView.getChildViewHolder(pressedView);
88 |
89 | if (isHeaderOrFooterPosition(vh.getLayoutPosition())) {
90 | return false;
91 | }
92 | childClickViewIds = vh.getChildClickViewIds();
93 |
94 | if (childClickViewIds != null && childClickViewIds.size() > 0) {
95 | for (Iterator it = childClickViewIds.iterator(); it.hasNext(); ) {
96 | View childView = pressedView.findViewById((Integer) it.next());
97 | if (inRangeOfView(childView, e)&&childView.isEnabled()) {
98 | onItemChildClick(baseQuickAdapter, childView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
99 | resetPressedView(pressedView);
100 | return true;
101 | }
102 | }
103 |
104 |
105 | onItemClick(baseQuickAdapter, pressedView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
106 | } else {
107 | onItemClick(baseQuickAdapter, pressedView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
108 | }
109 | resetPressedView(pressedView);
110 |
111 | }
112 | return true;
113 | }
114 |
115 | private void resetPressedView(final View pressedView) {
116 | if (pressedView!=null){
117 | pressedView.postDelayed(new Runnable() {
118 | @Override
119 | public void run() {
120 | if (pressedView!=null){
121 | pressedView.setPressed(false);
122 | }
123 |
124 | }
125 | }, 100);
126 | }
127 |
128 | mIsPrepressed = false;
129 | mPressedView = null;
130 | }
131 |
132 | @Override
133 | public void onLongPress(MotionEvent e) {
134 | boolean isChildLongClick =false;
135 | if (mIsPrepressed && mPressedView != null) {
136 | BaseViewHolder vh = (BaseViewHolder) recyclerView.getChildViewHolder(mPressedView);
137 | if (!isHeaderOrFooterPosition(vh.getLayoutPosition())) {
138 | longClickViewIds = vh.getItemChildLongClickViewIds();
139 | if (longClickViewIds != null && longClickViewIds.size() > 0) {
140 | for (Iterator it = longClickViewIds.iterator(); it.hasNext(); ) {
141 | View childView = mPressedView.findViewById((Integer) it.next());
142 | if (inRangeOfView(childView, e)&&childView.isEnabled()) {
143 | onItemChildLongClick(baseQuickAdapter, childView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
144 | mPressedView.setPressed(true);
145 | mIsShowPress = true;
146 | isChildLongClick =true;
147 | break;
148 | }
149 | }
150 | }
151 | if (!isChildLongClick){
152 | onItemLongClick(baseQuickAdapter, mPressedView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
153 | mPressedView.setPressed(true);
154 | mIsShowPress = true;
155 | }
156 |
157 | }
158 |
159 | }
160 | }
161 |
162 |
163 | }
164 |
165 | /**
166 | * Callback method to be invoked when an item in this AdapterView has
167 | * been clicked.
168 | *
169 | * @param view The view within the AdapterView that was clicked (this
170 | * will be a view provided by the adapter)
171 | * @param position The position of the view in the adapter.
172 | */
173 | public abstract void onItemClick(BaseQuickAdapter adapter, View view, int position);
174 |
175 | /**
176 | * callback method to be invoked when an item in this view has been
177 | * click and held
178 | *
179 | * @param view The view whihin the AbsListView that was clicked
180 | * @param position The position of the view int the adapter
181 | * @return true if the callback consumed the long click ,false otherwise
182 | */
183 | public abstract void onItemLongClick(BaseQuickAdapter adapter, View view, int position);
184 |
185 | public abstract void onItemChildClick(BaseQuickAdapter adapter, View view, int position);
186 |
187 | public abstract void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position);
188 |
189 | public boolean inRangeOfView(View view, MotionEvent ev) {
190 | int[] location = new int[2];
191 | if (view.getVisibility()!= View.VISIBLE){
192 | return false;
193 | }
194 | view.getLocationOnScreen(location);
195 | int x = location[0];
196 | int y = location[1];
197 | if (ev.getRawX() < x
198 | || ev.getRawX() > (x + view.getWidth())
199 | || ev.getRawY() < y
200 | || ev.getRawY() > (y + view.getHeight())) {
201 | return false;
202 | }
203 | return true;
204 | }
205 |
206 | private boolean isHeaderOrFooterPosition(int position) {
207 | /**
208 | * have a headview and EMPTY_VIEW FOOTER_VIEW LOADING_VIEW
209 | */
210 | int type = baseQuickAdapter.getItemViewType(position);
211 | return (type == BaseQuickAdapter.EMPTY_VIEW || type == BaseQuickAdapter.HEADER_VIEW || type == BaseQuickAdapter.FOOTER_VIEW || type == BaseQuickAdapter.LOADING_VIEW);
212 | }
213 |
214 | }
215 |
216 |
217 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/SlideInBottomAnimation.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.view.View;
6 |
7 |
8 | public class SlideInBottomAnimation implements BaseAnimation {
9 |
10 |
11 |
12 | @Override
13 | public Animator[] getAnimators(View view) {
14 | return new Animator[]{
15 | ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0)
16 | };
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/SlideInLeftAnimation.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.view.View;
6 |
7 |
8 | public class SlideInLeftAnimation implements BaseAnimation {
9 |
10 |
11 | @Override
12 | public Animator[] getAnimators(View view) {
13 | return new Animator[] {
14 | ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0)
15 | };
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/base/baseadapter/SlideInRightAnimation.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.base.baseadapter;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.view.View;
6 |
7 |
8 | public class SlideInRightAnimation implements BaseAnimation {
9 |
10 |
11 | @Override
12 | public Animator[] getAnimators(View view) {
13 | return new Animator[]{
14 | ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0)
15 | };
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/qyh/androidprojecthelper/baserx/RxBus.java:
--------------------------------------------------------------------------------
1 | package qyh.androidprojecthelper.baserx;
2 |
3 | import android.support.annotation.NonNull;
4 |
5 |
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collection;
9 | import java.util.List;
10 | import java.util.concurrent.ConcurrentHashMap;
11 |
12 | import rx.Observable;
13 | import rx.android.schedulers.AndroidSchedulers;
14 | import rx.functions.Action1;
15 | import rx.subjects.PublishSubject;
16 | import rx.subjects.Subject;
17 |
18 | /**
19 | * 用RxJava实现的EventBus
20 | * Created by qyh on 2016/8/6.
21 | */
22 | public class RxBus {
23 | private static RxBus instance;
24 |
25 | public static synchronized RxBus getInstance() {
26 | if (null == instance) {
27 | instance = new RxBus();
28 | }
29 | return instance;
30 | }
31 |
32 | private RxBus() {
33 | }
34 |
35 | @SuppressWarnings("rawtypes")
36 | private ConcurrentHashMap