├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── dictionaries
│ └── zzk.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── jsoup-1.8.3.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── lico
│ │ └── example
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── lico
│ │ │ └── example
│ │ │ ├── adapter
│ │ │ ├── BaseAdapterHelper.java
│ │ │ ├── BaseQuickAdapter.java
│ │ │ ├── ContentPagerAdapter.java
│ │ │ ├── SimpleRecyclerAdapter.java
│ │ │ └── TabFragmentPagerAdapter.java
│ │ │ ├── app
│ │ │ └── EApplication.java
│ │ │ ├── bean
│ │ │ ├── HttpResponseEntity.java
│ │ │ ├── ImagesListEntity.java
│ │ │ ├── JcodeInfo.java
│ │ │ └── ResponseImagesListEntity.java
│ │ │ ├── fragment
│ │ │ ├── ContentFragment.java
│ │ │ ├── ContentListFragment.java
│ │ │ ├── ImageFragment.java
│ │ │ ├── ImageListFragment.java
│ │ │ └── LazyFragment.java
│ │ │ ├── helper
│ │ │ ├── EventHelper.java
│ │ │ └── GenericHelper.java
│ │ │ ├── listener
│ │ │ ├── HttpApi.java
│ │ │ └── JSONParserCompleteListener.java
│ │ │ ├── presenter
│ │ │ ├── ActivityPresenter.java
│ │ │ ├── FragmentPresenter.java
│ │ │ └── IPresenter.java
│ │ │ ├── ui
│ │ │ ├── MainActivity.java
│ │ │ ├── PersonalActivity.java
│ │ │ └── SpaceImageDetailActivity.java
│ │ │ ├── utils
│ │ │ ├── BitmapUtil.java
│ │ │ └── DataUtil.java
│ │ │ ├── view
│ │ │ ├── ContentView.java
│ │ │ ├── ContentlistView.java
│ │ │ ├── IView.java
│ │ │ ├── ImageListView.java
│ │ │ ├── ImagesView.java
│ │ │ ├── MainView.java
│ │ │ ├── PersonalView.java
│ │ │ └── ViewImpl.java
│ │ │ └── views
│ │ │ ├── PLAImageView.java
│ │ │ ├── PullLoadMoreRecyclerView.java
│ │ │ ├── RecyclerViewOnScroll.java
│ │ │ ├── SmoothImageView.java
│ │ │ ├── SpacesItemDecoration.java
│ │ │ ├── SuperRecyclerView.java
│ │ │ └── SwipeRefreshLayoutOnRefresh.java
│ └── res
│ │ ├── drawable-v21
│ │ ├── ic_menu_camera.xml
│ │ ├── ic_menu_gallery.xml
│ │ ├── ic_menu_manage.xml
│ │ ├── ic_menu_send.xml
│ │ ├── ic_menu_share.xml
│ │ └── ic_menu_slideshow.xml
│ │ ├── drawable
│ │ ├── activated_background.xml
│ │ ├── selectable_background.xml
│ │ └── side_nav_bar.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── activity_personal.xml
│ │ ├── activity_test.xml
│ │ ├── app_bar_main.xml
│ │ ├── content_main.xml
│ │ ├── fragment_content.xml
│ │ ├── fragment_content_list.xml
│ │ ├── fragment_image.xml
│ │ ├── fragment_image_list.xml
│ │ ├── fragment_images.xml
│ │ ├── nav_header_main.xml
│ │ ├── toolbar_layout.xml
│ │ ├── view_content_list.xml
│ │ ├── view_footer.xml
│ │ ├── view_image_list_item.xml
│ │ └── view_pull_load_more.xml
│ │ ├── menu
│ │ ├── activity_main_drawer.xml
│ │ └── main.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ ├── avator.jpg
│ │ ├── bg_banner_dialog.jpg
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_discuss.png
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-v21
│ │ └── styles.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── arrays.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── drawables.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── lico
│ └── example
│ └── 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 | MVPExample
--------------------------------------------------------------------------------
/.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/dictionaries/zzk.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
24 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MVPExample
2 | 改良版MVP的demo; 涉及技术MVP activity模型、fragment模型(懒加载) 、retrofit 2.0 rxjava简单应用
3 |
4 | 项目中图片资源参考了简阅代码https://github.com/SkillCollege/SimplifyReader
5 |
6 | 因为电脑丢失:有些参考资料已经不记得了;
7 |
8 | 参考资料:http://kymjs.com/code/2015/11/09/01/
9 |
10 | http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3460.html
11 |
12 | https://github.com/lzyzsd/Awesome-RxJava中各种
13 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'me.tatarka.retrolambda'
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | applicationId "lico.example"
9 | minSdkVersion 11
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | compileOptions{
21 | sourceCompatibility 1.8
22 | targetCompatibility 1.8
23 | }
24 | }
25 |
26 |
27 |
28 | dependencies {
29 | compile fileTree(include: ['*.jar'], dir: 'libs')
30 | compile 'com.android.support:appcompat-v7:23.1.1'
31 | compile 'com.android.support:design:23.1.1'
32 | compile 'com.jakewharton:butterknife:7.0.0'
33 | compile 'io.reactivex:rxandroid:1.0.0'
34 | compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
35 | compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
36 | compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
37 | compile 'com.google.code.gson:gson:2.3.1'
38 | compile 'com.squareup.okhttp:okhttp:2.4.0'
39 | compile 'com.jcodecraeer:xrecyclerview:1.2.5'
40 | compile 'com.github.bumptech.glide:glide:3.6.0'
41 | debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
42 | releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
43 | compile 'com.android.support:cardview-v7:23.1.1'
44 | compile 'com.facebook.fresco:fresco:0.8.1+'
45 | compile files('libs/jsoup-1.8.3.jar')
46 | }
47 |
--------------------------------------------------------------------------------
/app/libs/jsoup-1.8.3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/libs/jsoup-1.8.3.jar
--------------------------------------------------------------------------------
/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 /Users/zzk/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/lico/example/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package lico.example;
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 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/adapter/BaseAdapterHelper.java:
--------------------------------------------------------------------------------
1 | package lico.example.adapter;
2 |
3 | import android.net.Uri;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.util.SparseArray;
6 | import android.view.View;
7 | import android.widget.Button;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import com.bumptech.glide.Glide;
12 | import com.facebook.drawee.view.SimpleDraweeView;
13 |
14 | import lico.example.app.EApplication;
15 | import lico.example.views.PLAImageView;
16 |
17 |
18 | /**
19 | * Created by zwl on 2015/8/25.
20 | */
21 | public class BaseAdapterHelper extends RecyclerView.ViewHolder {
22 |
23 | private SparseArray views;
24 |
25 |
26 | public BaseAdapterHelper(View itemView) {
27 | super(itemView);
28 | this.views = new SparseArray();
29 | }
30 |
31 | public void setText(int viewId, String str) {
32 | View view = retrieveView(viewId);
33 | if (view instanceof TextView) {
34 | ((TextView) view).setText(str);
35 | } else if (view instanceof Button) {
36 | ((Button) view).setText(str);
37 | }
38 | }
39 |
40 | public void setImageByUrl(int viewId, String url) {
41 | View view = retrieveView(viewId);
42 | // if(view instanceof RatioImageView){ //普通图片用glide加载
43 | // Glide.with(EApplication.getInstance()).load(url)
44 | // .crossFade().into((RatioImageView)view);
45 | // }else if(view instanceof PLAImageView){
46 | // Glide.with(EApplication.getInstance()).load(url)
47 | // .crossFade().into((PLAImageView) view);
48 | // }else if(view instanceof SquaredImageView){
49 | // Glide.with(EApplication.getInstance()).load(url)
50 | // .crossFade().into((SquaredImageView) view);
51 | // }else
52 | if (view instanceof PLAImageView) {
53 | Glide.with(EApplication.getInstance()).load(url)
54 | .crossFade().into((PLAImageView) view);
55 | } else if (view instanceof ImageView) {
56 | Glide.with(EApplication.getInstance()).load(url)
57 | .crossFade().into((ImageView) view);
58 | } else if (view instanceof SimpleDraweeView) {
59 | Uri uri = Uri.parse(url);
60 | ((SimpleDraweeView) view).setImageURI(uri);
61 | }
62 | }
63 |
64 | public TextView getTextView(int viewId) {
65 | return retrieveView(viewId);
66 | }
67 |
68 | public Button getButton(int viewId) {
69 | return retrieveView(viewId);
70 | }
71 |
72 | public ImageView getImageView(int viewId) {
73 | return retrieveView(viewId);
74 | }
75 |
76 | public View getView(int viewId) {
77 | return retrieveView(viewId);
78 | }
79 |
80 | protected T retrieveView(int viewId) {
81 | View view = views.get(viewId);
82 | if (view == null) {
83 | view = itemView.findViewById(viewId);
84 | views.put(viewId, view);
85 | }
86 | return (T) view;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/adapter/BaseQuickAdapter.java:
--------------------------------------------------------------------------------
1 | package lico.example.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 |
14 | /**
15 | * Created by zwl on 2015/8/25.
16 | */
17 | public abstract class BaseQuickAdapter extends RecyclerView.Adapter {
18 | protected static final String TAG = BaseQuickAdapter.class.getSimpleName();
19 |
20 | protected final Context mContext;
21 |
22 | protected final int mLayoutResId;
23 |
24 | protected final List data;
25 |
26 | private Map> canClickItem;
27 |
28 | public BaseQuickAdapter(Context mContext, int mLayoutResId) {
29 | this(mContext, mLayoutResId, null);
30 | setHasStableIds(true);
31 | }
32 |
33 | public BaseQuickAdapter(Context mContext, int mLayoutResId, List data) {
34 | this.mContext = mContext;
35 | this.mLayoutResId = mLayoutResId;
36 | this.data = data;
37 | }
38 |
39 | @Override
40 | public BaseAdapterHelper onCreateViewHolder(ViewGroup parent, int viewType) {
41 | View view = LayoutInflater.from(parent.getContext()).inflate(mLayoutResId, parent, false);
42 | BaseAdapterHelper vh = new BaseAdapterHelper(view);
43 | return vh;
44 | }
45 |
46 | @Override
47 | public void onBindViewHolder(BaseAdapterHelper holder, int position) {
48 | if (holder != null) {
49 | addInternalClickListener(holder.itemView, position, data.get(position));
50 | }
51 | holder.itemView.setTag(position);
52 | T item = getItem(position);
53 | convert((H) holder, item);
54 | }
55 |
56 | public List getDataList() {
57 | return data;
58 | }
59 |
60 | @Override
61 | public int getItemCount() {
62 | return data.size();
63 | }
64 |
65 | public T getItem(int position) {
66 | if (position >= data.size())
67 | return null;
68 | return data.get(position);
69 | }
70 |
71 | protected abstract void convert(H helper, T item);
72 |
73 | private void addInternalClickListener(final View itemV, final Integer position, final T valuesMap) {
74 | if (canClickItem != null) {
75 | for (Integer key : canClickItem.keySet()) {
76 | View inView = itemV.findViewById(key);
77 | final onInternalClickListener listener = canClickItem.get(key);
78 | if (inView != null && listener != null) {
79 | inView.setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View view) {
82 | listener.OnClickListener(itemV, view, position, valuesMap);
83 | }
84 | });
85 | inView.setOnLongClickListener(new View.OnLongClickListener() {
86 | @Override
87 | public boolean onLongClick(View view) {
88 | listener.OnLongClickListener(itemV, view, position,
89 | valuesMap);
90 | return true;
91 | }
92 | });
93 | }
94 | }
95 | }
96 | }
97 |
98 | public void setOnInViewClickListener(Integer key, onInternalClickListener onClickListener) {
99 | if (canClickItem == null)
100 | canClickItem = new HashMap>();
101 | canClickItem.put(key, onClickListener);
102 |
103 | }
104 |
105 | public interface onInternalClickListener {
106 | void OnClickListener(View parentV, View v, Integer position, T values);
107 |
108 | void OnLongClickListener(View parentV, View v, Integer position, T values);
109 | }
110 |
111 | public static class onInternalClickListenerImpl implements onInternalClickListener {
112 | @Override
113 | public void OnClickListener(View parentV, View v, Integer position, T values) {
114 |
115 | }
116 |
117 | @Override
118 | public void OnLongClickListener(View parentV, View v, Integer position, T values) {
119 |
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/adapter/ContentPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package lico.example.adapter;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | import lico.example.fragment.ContentListFragment;
12 |
13 | /**
14 | * Created by zzk on 15/12/22.
15 | */
16 | public class ContentPagerAdapter extends FragmentPagerAdapter {
17 |
18 | private List mFragmentTitles = new ArrayList<>();
19 | private List tids = new ArrayList<>();
20 |
21 | public ContentPagerAdapter(FragmentManager fm, List strings, List ids) {
22 | super(fm);
23 | this.mFragmentTitles = strings;
24 | this.tids = ids;
25 | }
26 |
27 | @Override
28 | public Fragment getItem(int position) {
29 | return ContentListFragment.newInstance(tids.get(position));
30 | }
31 |
32 | @Override
33 | public int getCount() {
34 | return mFragmentTitles == null ? 0 : mFragmentTitles.size();
35 | }
36 |
37 | @Override
38 | public CharSequence getPageTitle(int position) {
39 | return mFragmentTitles == null ? null : mFragmentTitles.get(position);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/adapter/SimpleRecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package lico.example.adapter;
2 |
3 | import android.content.Context;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * Created by Administrator on 2015/8/25.
9 | */
10 | public abstract class SimpleRecyclerAdapter extends BaseQuickAdapter {
11 |
12 |
13 | public SimpleRecyclerAdapter(Context mContext, List data, int mLayoutResId) {
14 | super(mContext, mLayoutResId, data);
15 | }
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/adapter/TabFragmentPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package lico.example.adapter;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import lico.example.fragment.ContentListFragment;
11 | import lico.example.fragment.ImageListFragment;
12 |
13 | /**
14 | * Created by zwl on 2015/8/31.
15 | */
16 | public class TabFragmentPagerAdapter extends FragmentPagerAdapter {
17 |
18 | private List mFragmentTitles = new ArrayList<>();
19 | private int mType;
20 |
21 | public TabFragmentPagerAdapter(FragmentManager fm, List strings, int type) {
22 | super(fm);
23 | this.mFragmentTitles = strings;
24 | mType = type;
25 | }
26 |
27 | @Override
28 | public Fragment getItem(int position) {
29 | if (mType == 1){
30 | return ImageListFragment.newInstance(mFragmentTitles.get(position));
31 | } else {
32 | return ContentListFragment.newInstance(mFragmentTitles.get(position));
33 | }
34 |
35 | }
36 |
37 | @Override
38 | public int getCount() {
39 | return mFragmentTitles == null ? 0 : mFragmentTitles.size();
40 | }
41 |
42 | @Override
43 | public CharSequence getPageTitle(int position) {
44 | return mFragmentTitles == null ? null : mFragmentTitles.get(position);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/app/EApplication.java:
--------------------------------------------------------------------------------
1 | package lico.example.app;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.drawee.backends.pipeline.Fresco;
6 | import com.squareup.leakcanary.LeakCanary;
7 |
8 |
9 | /**
10 | * Created by zzk on 15/12/7.
11 | */
12 | public class EApplication extends Application{
13 | private static EApplication instance = null;
14 | @Override
15 | public void onCreate() {
16 | super.onCreate();
17 | instance = this;
18 | Fresco.initialize(this) ;
19 | LeakCanary.install(this);
20 | }
21 |
22 | public static EApplication getInstance(){
23 | if(instance == null){
24 | synchronized (EApplication.class){
25 | if(instance == null){
26 | instance = new EApplication();
27 | }
28 | }
29 | }
30 | return instance;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/bean/HttpResponseEntity.java:
--------------------------------------------------------------------------------
1 | package lico.example.bean;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by zwl on 15/7/27.
7 | */
8 | public class HttpResponseEntity implements Serializable {
9 | public int responseCode;
10 | public String errorMsg;
11 |
12 | public HttpResponseEntity(int responseCode, String errorMsg) {
13 | this.responseCode = responseCode;
14 | this.errorMsg = errorMsg;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/bean/ImagesListEntity.java:
--------------------------------------------------------------------------------
1 | package lico.example.bean;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Created by zwl on 2015/9/23.
10 | */
11 | public class ImagesListEntity implements Parcelable {
12 |
13 | public String id;
14 | public String desc;
15 | public List tags;
16 | public String fromPageTitle;
17 | public String column;
18 | public String date;
19 | public String downloadUrl;
20 | public String imageUrl;
21 | public int imageWidth;
22 | public int imageHeight;
23 | public String thumbnailUrl;
24 | public int thumbnailWidth;
25 | public int thumbnailHeight;
26 | public String thumbnailLargeUrl;
27 | public int thumbnailLargeWidth;
28 | public int thumbnailLargeHeight;
29 | public String thumbnailLargeTnUrl;
30 | public int thumbnailLargeTnWidth;
31 | public int thumbnailLargeTnHeight;
32 | public String siteName;
33 | public String siteLogo;
34 | public String siteUrl;
35 | public String fromUrl;
36 | public String objUrl;
37 | public String shareUrl;
38 | public String albumId;
39 | public int isAlbum;
40 | public String albumName;
41 | public int albumNum;
42 | public String title;
43 |
44 |
45 | @Override
46 | public int describeContents() {
47 | return 0;
48 | }
49 |
50 | @Override
51 | public void writeToParcel(Parcel dest, int flags) {
52 | dest.writeString(this.id);
53 | dest.writeString(this.desc);
54 | dest.writeStringList(this.tags);
55 | dest.writeString(this.fromPageTitle);
56 | dest.writeString(this.column);
57 | dest.writeString(this.date);
58 | dest.writeString(this.downloadUrl);
59 | dest.writeString(this.imageUrl);
60 | dest.writeInt(this.imageWidth);
61 | dest.writeInt(this.imageHeight);
62 | dest.writeString(this.thumbnailUrl);
63 | dest.writeInt(this.thumbnailWidth);
64 | dest.writeString(this.thumbnailLargeUrl);
65 | dest.writeInt(this.thumbnailHeight);
66 | dest.writeInt(this.thumbnailLargeWidth);
67 | dest.writeInt(this.thumbnailLargeHeight);
68 | dest.writeString(this.thumbnailLargeTnUrl);
69 | dest.writeInt(this.thumbnailLargeTnWidth);
70 | dest.writeInt(this.thumbnailLargeTnHeight);
71 | dest.writeString(this.siteName);
72 | dest.writeString(this.siteLogo);
73 | dest.writeString(this.siteUrl);
74 | dest.writeString(this.fromUrl);
75 | dest.writeString(this.objUrl);
76 | dest.writeString(this.shareUrl);
77 | dest.writeString(this.albumId);
78 | dest.writeInt(this.isAlbum);
79 | dest.writeString(this.albumName);
80 | dest.writeInt(this.albumNum);
81 | dest.writeString(this.title);
82 | }
83 |
84 | public ImagesListEntity() {
85 | }
86 |
87 | protected ImagesListEntity(Parcel in) {
88 | this.id = in.readString();
89 | this.desc = in.readString();
90 | this.tags = in.createStringArrayList();
91 | this.fromPageTitle = in.readString();
92 | this.column = in.readString();
93 | this.date = in.readString();
94 | this.downloadUrl = in.readString();
95 | this.imageUrl = in.readString();
96 | this.imageWidth = in.readInt();
97 | this.imageHeight = in.readInt();
98 | this.thumbnailUrl = in.readString();
99 | this.thumbnailWidth = in.readInt();
100 | this.thumbnailLargeUrl = in.readString();
101 | this.thumbnailHeight = in.readInt();
102 | this.thumbnailLargeWidth = in.readInt();
103 | this.thumbnailLargeHeight = in.readInt();
104 | this.thumbnailLargeTnUrl = in.readString();
105 | this.thumbnailLargeTnWidth = in.readInt();
106 | this.thumbnailLargeTnHeight = in.readInt();
107 | this.siteName = in.readString();
108 | this.siteLogo = in.readString();
109 | this.siteUrl = in.readString();
110 | this.fromUrl = in.readString();
111 | this.objUrl = in.readString();
112 | this.shareUrl = in.readString();
113 | this.albumId = in.readString();
114 | this.isAlbum = in.readInt();
115 | this.albumName = in.readString();
116 | this.albumNum = in.readInt();
117 | this.title = in.readString();
118 | }
119 |
120 | public static final Creator CREATOR = new Creator() {
121 | public ImagesListEntity createFromParcel(Parcel source) {
122 | return new ImagesListEntity(source);
123 | }
124 |
125 | public ImagesListEntity[] newArray(int size) {
126 | return new ImagesListEntity[size];
127 | }
128 | };
129 | }
130 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/bean/JcodeInfo.java:
--------------------------------------------------------------------------------
1 | package lico.example.bean;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | /**
7 | * Created by zzk on 15/12/30.
8 | * 泡在网上的日子 数据实体类 http://www.jcodecraeer.com/
9 | */
10 | public class JcodeInfo implements Parcelable{
11 |
12 | public String detailUrl;
13 | public String imageUrl;
14 | public String title;
15 |
16 |
17 | @Override
18 | public int describeContents() {
19 | return 0;
20 | }
21 |
22 | @Override
23 | public void writeToParcel(Parcel dest, int flags) {
24 | dest.writeString(this.detailUrl);
25 | dest.writeString(this.imageUrl);
26 | dest.writeString(this.title);
27 | }
28 |
29 | public JcodeInfo() {
30 | }
31 |
32 | protected JcodeInfo(Parcel in) {
33 | this.detailUrl = in.readString();
34 | this.imageUrl = in.readString();
35 | this.title = in.readString();
36 | }
37 |
38 | public static final Creator CREATOR = new Creator() {
39 | public JcodeInfo createFromParcel(Parcel source) {
40 | return new JcodeInfo(source);
41 | }
42 |
43 | public JcodeInfo[] newArray(int size) {
44 | return new JcodeInfo[size];
45 | }
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/bean/ResponseImagesListEntity.java:
--------------------------------------------------------------------------------
1 | package lico.example.bean;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Created by zwl on 2015/9/23.
10 | */
11 | public class ResponseImagesListEntity implements Parcelable {
12 |
13 | public String col;
14 | public String tag;
15 | public String tag3;
16 | public String sort;
17 | public int totalNum;
18 | public int startIndex;
19 | public int returnNumber;
20 | public List imgs;
21 |
22 |
23 | @Override
24 | public int describeContents() {
25 | return 0;
26 | }
27 |
28 | @Override
29 | public void writeToParcel(Parcel dest, int flags) {
30 | dest.writeString(this.col);
31 | dest.writeString(this.tag);
32 | dest.writeString(this.tag3);
33 | dest.writeString(this.sort);
34 | dest.writeInt(this.totalNum);
35 | dest.writeInt(this.startIndex);
36 | dest.writeInt(this.returnNumber);
37 | dest.writeTypedList(imgs);
38 | }
39 |
40 | public ResponseImagesListEntity() {
41 | }
42 |
43 | protected ResponseImagesListEntity(Parcel in) {
44 | this.col = in.readString();
45 | this.tag = in.readString();
46 | this.tag3 = in.readString();
47 | this.sort = in.readString();
48 | this.totalNum = in.readInt();
49 | this.startIndex = in.readInt();
50 | this.returnNumber = in.readInt();
51 | this.imgs = in.createTypedArrayList(ImagesListEntity.CREATOR);
52 | }
53 |
54 | public static final Creator CREATOR = new Creator() {
55 | public ResponseImagesListEntity createFromParcel(Parcel source) {
56 | return new ResponseImagesListEntity(source);
57 | }
58 |
59 | public ResponseImagesListEntity[] newArray(int size) {
60 | return new ResponseImagesListEntity[size];
61 | }
62 | };
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/fragment/ContentFragment.java:
--------------------------------------------------------------------------------
1 | package lico.example.fragment;
2 |
3 | import android.content.Context;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | import lico.example.R;
9 | import lico.example.presenter.FragmentPresenter;
10 | import lico.example.view.ContentView;
11 | import rx.Observable;
12 | import rx.Subscriber;
13 | import rx.android.schedulers.AndroidSchedulers;
14 | import rx.functions.Func1;
15 |
16 | /**
17 | * Created by zzk on 15/12/22.
18 | */
19 | public class ContentFragment extends FragmentPresenter {
20 |
21 | private String[] ids = new String[]{"6", "18", "5", "27", "14"};
22 |
23 | @Override
24 | protected void initData() {
25 | super.initData();
26 | getTitle(getActivity());
27 | }
28 |
29 | private void getTitle(Context context) {
30 | Observable.just(1)
31 | .map(new Func1>() {
32 |
33 | @Override
34 | public List call(Integer integer) {
35 | return getList();
36 | }
37 | })
38 | .observeOn(AndroidSchedulers.mainThread())
39 | .subscribe(new Subscriber>() {
40 | @Override
41 | public void onCompleted() {
42 |
43 | }
44 |
45 | @Override
46 | public void onError(Throwable e) {
47 |
48 | }
49 |
50 | @Override
51 | public void onNext(List list) {
52 | mView.initViewPager(list.get(0), list.get(1), getChildFragmentManager());
53 | }
54 | });
55 | }
56 |
57 | private List getList() {
58 | List list = new ArrayList<>();
59 | list.add(getResources().getStringArray(R.array.archive_list));
60 | list.add(ids);
61 |
62 | return list;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/fragment/ContentListFragment.java:
--------------------------------------------------------------------------------
1 | package lico.example.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 |
6 | import java.util.List;
7 |
8 | import lico.example.bean.JcodeInfo;
9 | import lico.example.presenter.FragmentPresenter;
10 | import lico.example.utils.DataUtil;
11 | import lico.example.view.ContentListView;
12 | import lico.example.views.PullLoadMoreRecyclerView;
13 |
14 | import rx.Observable;
15 | import rx.Subscriber;
16 | import rx.android.schedulers.AndroidSchedulers;
17 | import rx.functions.Func1;
18 | import rx.schedulers.Schedulers;
19 |
20 | /**
21 | * Created by zzk on 15/12/22.
22 | */
23 | public class ContentListFragment extends FragmentPresenter implements PullLoadMoreRecyclerView.PullLoadMoreListener {
24 |
25 | String tid;
26 | boolean isRefresh = true;
27 | int page = 1;
28 |
29 | public static ContentListFragment newInstance(String id) {
30 | ContentListFragment contentListFragment = new ContentListFragment();
31 | Bundle bundle = new Bundle();
32 | bundle.putString("tid", id);
33 | contentListFragment.setArguments(bundle);
34 | return contentListFragment;
35 | }
36 |
37 | @Override
38 | protected void lazyData() {
39 | super.lazyData();
40 |
41 | mView.initViews(getActivity(), this);
42 | getData();
43 | }
44 |
45 | private void getData() {
46 | tid = getArguments().getString("tid");
47 | Observable.just("")
48 | .map(new Func1>() {
49 | @Override
50 | public List call(String s) {
51 | return DataUtil.getJcodeData(tid, page);
52 | }
53 | })
54 | .observeOn(AndroidSchedulers.mainThread())
55 | .subscribeOn(Schedulers.newThread())
56 | .subscribe(new Subscriber>() {
57 | @Override
58 | public void onCompleted() {
59 | }
60 |
61 | @Override
62 | public void onError(Throwable e) {
63 | }
64 |
65 | @Override
66 | public void onNext(List jcodeInfos) {
67 | Log.e("x", "xx : " + jcodeInfos.size());
68 | if (isRefresh) mView.refreshListData(jcodeInfos);
69 | else mView.addListData(jcodeInfos);
70 | }
71 | });
72 | }
73 |
74 | @Override
75 | public void onRefresh() {
76 | isRefresh = true;
77 | page = 1;
78 | getData();
79 | }
80 |
81 | @Override
82 | public void onLoadMore() {
83 | isRefresh = false;
84 | page++;
85 | getData();
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/fragment/ImageFragment.java:
--------------------------------------------------------------------------------
1 | package lico.example.fragment;
2 |
3 | import android.content.Context;
4 |
5 | import lico.example.R;
6 | import lico.example.presenter.FragmentPresenter;
7 | import lico.example.view.ImagesView;
8 | import rx.Observable;
9 | import rx.Subscriber;
10 | import rx.android.schedulers.AndroidSchedulers;
11 | import rx.functions.Func1;
12 |
13 | /**
14 | * Created by zzk on 15/11/28.
15 | */
16 | public class ImageFragment extends FragmentPresenter{
17 |
18 |
19 | @Override
20 | protected void initData() { //不是懒加载
21 | super.initData();
22 | getTitles(getActivity());
23 | }
24 |
25 | private void getTitles(Context context){
26 |
27 | Observable.just(R.array.images_category_list)
28 | .map(new Func1() {
29 |
30 | @Override
31 | public String[] call(Integer integer) {
32 | return context.getResources().getStringArray(R.array.images_category_list);
33 | }
34 | })
35 | .observeOn(AndroidSchedulers.mainThread())
36 | .subscribe(new Subscriber() {
37 | @Override
38 | public void onCompleted() {
39 |
40 | }
41 |
42 | @Override
43 | public void onError(Throwable e) {
44 |
45 | }
46 |
47 | @Override
48 | public void onNext(String[] strings) {
49 | mView.initViewPager(strings, getFragmentManager());
50 | }
51 | });
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/fragment/ImageListFragment.java:
--------------------------------------------------------------------------------
1 | package lico.example.fragment;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.jcodecraeer.xrecyclerview.XRecyclerView;
6 |
7 |
8 | import lico.example.bean.ResponseImagesListEntity;
9 | import lico.example.listener.HttpApi;
10 | import lico.example.presenter.FragmentPresenter;
11 | import lico.example.view.ImageListView;
12 | import retrofit.GsonConverterFactory;
13 | import retrofit.Retrofit;
14 | import retrofit.RxJavaCallAdapterFactory;
15 | import rx.Subscriber;
16 | import rx.android.schedulers.AndroidSchedulers;
17 | import rx.schedulers.Schedulers;
18 |
19 | /**
20 | * Created by zzk on 15/12/7.
21 | */
22 | public class ImageListFragment extends FragmentPresenter implements XRecyclerView.LoadingListener{
23 |
24 | boolean isRefresh = true;
25 | String keyword;
26 | int page = 0;
27 |
28 | public static ImageListFragment newInstance(String title) {
29 | ImageListFragment imageListFragment = new ImageListFragment();
30 | Bundle bundle = new Bundle();
31 | bundle.putString("keyword", title);
32 | imageListFragment.setArguments(bundle);
33 | return imageListFragment;
34 | }
35 |
36 | @Override
37 | protected void lazyData() {
38 | super.lazyData();
39 | mView.initViews(getActivity(), this);
40 | getData();
41 | }
42 |
43 | private void getData() {
44 | keyword = getArguments().getString("keyword");
45 | Retrofit retrofit = new Retrofit.Builder()
46 | .baseUrl("http://image.baidu.com")
47 | .addConverterFactory(GsonConverterFactory.create())
48 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
49 | .build();
50 | HttpApi api = retrofit.create(HttpApi.class);
51 | api.getImagess(keyword, "全部", page*10, 10, 1)
52 | .observeOn(AndroidSchedulers.mainThread())
53 | .subscribeOn(Schedulers.newThread())
54 | .subscribe(new Subscriber() {
55 | @Override
56 | public void onCompleted() {}
57 |
58 | @Override
59 | public void onError(Throwable e) {}
60 |
61 | @Override
62 | public void onNext(ResponseImagesListEntity entity) {
63 | if(isRefresh) mView.refreshListData(entity.imgs);
64 | mView.addListData(entity.imgs);
65 | }
66 | });
67 |
68 | }
69 |
70 | @Override
71 | public void onRefresh() {
72 | isRefresh = true;
73 | page = 0;
74 | getData();
75 | }
76 |
77 | @Override
78 | public void onLoadMore() {
79 | isRefresh = false;
80 | page++;
81 | getData();
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/fragment/LazyFragment.java:
--------------------------------------------------------------------------------
1 | package lico.example.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | /**
11 | * Created by zzk on 15/11/26.
12 | */
13 | public abstract class LazyFragment extends Fragment{
14 |
15 | private boolean isVisible;
16 |
17 | private boolean isPrepared;
18 |
19 | private boolean isFirstLoad = true;
20 |
21 | @Nullable
22 | @Override
23 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
24 | isFirstLoad = true;
25 | View view = initViews(inflater, container, savedInstanceState);
26 | isPrepared = true;
27 | lazyLoad();
28 | return view;
29 | }
30 |
31 | @Override
32 | public void setUserVisibleHint(boolean isVisibleToUser) {
33 | super.setUserVisibleHint(isVisibleToUser);
34 | if(getUserVisibleHint()){
35 | isVisible = true;
36 | onVisible();
37 | } else {
38 | isVisible = false;
39 | onInvisible();
40 | }
41 | }
42 |
43 | @Override
44 | public void onHiddenChanged(boolean hidden) {
45 | super.onHiddenChanged(hidden);
46 | if(!hidden){
47 | isVisible = true;
48 | onVisible();
49 | } else {
50 | isVisible = false;
51 | onInvisible();
52 | }
53 | }
54 |
55 | protected void onVisible(){
56 | lazyLoad();
57 | }
58 |
59 | protected void onInvisible(){
60 |
61 | }
62 |
63 | protected void lazyLoad(){
64 | if(!isPrepared || !isVisible || !isFirstLoad){
65 | return;
66 | }
67 | isFirstLoad = false;
68 | initializeData();
69 | }
70 |
71 | protected abstract View initViews(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
72 |
73 | protected abstract void initializeData();
74 |
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/helper/EventHelper.java:
--------------------------------------------------------------------------------
1 | package lico.example.helper;
2 |
3 | import android.support.design.widget.NavigationView;
4 | import android.view.View;
5 |
6 | import lico.example.presenter.IPresenter;
7 |
8 | /**
9 | * Created by zzk on 15/11/27.
10 | */
11 | public class EventHelper {
12 |
13 | public static void click(IPresenter presenter, View ...views){
14 | if(!(presenter instanceof View.OnClickListener)) return;
15 | if(views == null || views.length == 0) return;
16 | for (View v : views) v.setOnClickListener((View.OnClickListener) presenter);
17 | }
18 |
19 | public static void setNavigationItemSelected(IPresenter presenter, View ...views){
20 | if(!(presenter instanceof NavigationView.OnNavigationItemSelectedListener)) return;
21 | if(views == null || views.length == 0) return;
22 | for (View v : views) ((NavigationView)v).setNavigationItemSelectedListener((NavigationView.OnNavigationItemSelectedListener) presenter);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/helper/GenericHelper.java:
--------------------------------------------------------------------------------
1 | package lico.example.helper;
2 |
3 | import java.lang.reflect.ParameterizedType;
4 | import java.lang.reflect.Type;
5 |
6 | /**
7 | * Created by zzk on 15/11/27.
8 | */
9 | public class GenericHelper {
10 |
11 | public static Class getViewClass(Class> klass){
12 | Type type = klass.getGenericSuperclass();
13 | if(type == null || !(type instanceof ParameterizedType)) return null;
14 | ParameterizedType parameterizedType = (ParameterizedType) type;
15 | Type[] types = parameterizedType.getActualTypeArguments();
16 | if(types == null || types.length == 0) return null;
17 | return (Class) types[0];
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/listener/HttpApi.java:
--------------------------------------------------------------------------------
1 | package lico.example.listener;
2 |
3 | import lico.example.bean.ResponseImagesListEntity;
4 | import retrofit.http.GET;
5 | import retrofit.http.Query;
6 | import rx.Observable;
7 |
8 |
9 | /**
10 | * Created by zzk on 15/12/7.
11 | */
12 | public interface HttpApi {
13 |
14 | @GET("/data/imgs")
15 | Observable getImagess(@Query("col") String col,@Query("tag")String tag, @Query("pn") int pn, @Query("rn") int rn, @Query("from") int from);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/listener/JSONParserCompleteListener.java:
--------------------------------------------------------------------------------
1 | package lico.example.listener;
2 |
3 |
4 | import lico.example.bean.HttpResponseEntity;
5 |
6 | /**
7 | * Created by zwl on 15/7/27.
8 | */
9 | public interface JSONParserCompleteListener {
10 | public void ParserCompleteListener(HttpResponseEntity response, Object object);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/presenter/ActivityPresenter.java:
--------------------------------------------------------------------------------
1 | package lico.example.presenter;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.support.v7.widget.Toolbar;
6 | import android.view.Menu;
7 |
8 | import lico.example.helper.GenericHelper;
9 | import lico.example.view.IView;
10 |
11 | /**
12 | * Created by zzk on 15/11/26.
13 | */
14 | public class ActivityPresenter extends AppCompatActivity implements IPresenter {
15 |
16 | protected T mView;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | try {
22 | mView = getViewClass().newInstance();
23 | mView.create(getLayoutInflater(), null);
24 | mView.bindPresenter(this);
25 | setContentView(mView.getRootView());
26 | initToolbar();
27 | mView.bindEvent();
28 | initData();
29 | } catch (InstantiationException e) {
30 | e.printStackTrace();
31 | } catch (IllegalAccessException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 |
36 | protected void initToolbar() {
37 | Toolbar toolbar = mView.getToolbar();
38 | if (null != toolbar) {
39 | setSupportActionBar(toolbar);
40 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
41 | }
42 | }
43 |
44 | @Override
45 | public boolean onCreateOptionsMenu(Menu menu) {
46 | if (mView.getOptionsMenuId() != 0) {
47 | getMenuInflater().inflate(mView.getOptionsMenuId(), menu);
48 | }
49 | return super.onCreateOptionsMenu(menu);
50 | }
51 |
52 | @Override
53 | protected void onDestroy() {
54 | mView.destroy();
55 | super.onDestroy();
56 | }
57 |
58 | protected void initData(){}
59 |
60 | @Override
61 | public Class getViewClass() {
62 | return GenericHelper.getViewClass(getClass());
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/presenter/FragmentPresenter.java:
--------------------------------------------------------------------------------
1 | package lico.example.presenter;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import lico.example.fragment.LazyFragment;
9 | import lico.example.helper.GenericHelper;
10 | import lico.example.view.IView;
11 |
12 | /**
13 | * Created by zzk on 15/11/26.
14 | */
15 | public class FragmentPresenter extends LazyFragment implements IPresenter{
16 |
17 | protected T mView;
18 |
19 | @Override
20 | protected View initViews(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
21 | View view = null;
22 | try{
23 | mView = getViewClass().newInstance();
24 | mView.create(inflater, container);
25 | mView.bindPresenter(this);
26 | view = mView.getRootView();
27 | initData();
28 | }catch (Exception e){
29 | e.printStackTrace();
30 | }
31 | return view;
32 | }
33 |
34 |
35 |
36 | @Override
37 | protected void initializeData() {//懒加载在这里,so在写个方法让子类去实现
38 | lazyData();
39 | }
40 |
41 | @Override
42 | public void onDestroyView() {
43 | onDestroyV();
44 | mView = null;
45 | super.onDestroyView();
46 | }
47 |
48 | protected void onDestroyV() {
49 | }
50 |
51 | protected void initData(){}
52 |
53 | protected void lazyData(){}
54 |
55 | @Override
56 | public Class getViewClass() {
57 | return GenericHelper.getViewClass(getClass());
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/presenter/IPresenter.java:
--------------------------------------------------------------------------------
1 | package lico.example.presenter;
2 |
3 | /**
4 | * Created by zzk on 15/11/27.
5 | */
6 | public interface IPresenter {
7 | Class getViewClass();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/ui/MainActivity.java:
--------------------------------------------------------------------------------
1 | package lico.example.ui;
2 |
3 | import android.content.Intent;
4 | import android.graphics.Bitmap;
5 | import android.view.View;
6 | import android.support.design.widget.NavigationView;
7 | import android.view.MenuItem;
8 |
9 | import lico.example.R;
10 | import lico.example.presenter.ActivityPresenter;
11 | import lico.example.utils.BitmapUtil;
12 | import lico.example.view.MainView;
13 | import rx.Observable;
14 | import rx.Subscriber;
15 | import rx.android.schedulers.AndroidSchedulers;
16 | import rx.functions.Func1;
17 |
18 | public class MainActivity extends ActivityPresenter
19 | implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener {
20 |
21 | @Override
22 | protected void initData() {
23 | super.initData();
24 | getBitmap();
25 | mView.setNavigationItemSelected(getSupportFragmentManager(), R.id.nav_camera);
26 | }
27 |
28 | @Override
29 | public boolean onOptionsItemSelected(MenuItem item) {
30 | return mView.setOptionsItemSelected(item.getItemId());
31 | }
32 |
33 | @SuppressWarnings("StatementWithEmptyBody")
34 | @Override
35 | public boolean onNavigationItemSelected(MenuItem item) {
36 | return mView.setNavigationItemSelected(getSupportFragmentManager(), item.getItemId());
37 | }
38 |
39 | @Override
40 | public void onClick(View v) {
41 | switch (v.getId()) {
42 | case R.id.fab:
43 | mView.setFabClick("我的天呐");
44 | break;
45 | case R.id.imageView:
46 | Intent intent = new Intent(this, PersonalActivity.class);
47 | startActivity(intent);
48 | break;
49 | }
50 | }
51 |
52 | @Override
53 | public void onBackPressed() {
54 | if (mView.closeDrawer())
55 | return;
56 | super.onBackPressed();
57 | }
58 |
59 | private void getBitmap() {
60 | Observable.just(R.mipmap.avator)
61 | .map(new Func1() {
62 | @Override
63 | public Bitmap call(Integer integer) {
64 | return BitmapUtil.matrixBitmap(MainActivity.this, integer);
65 | }
66 | })
67 | .map(new Func1() {
68 | @Override
69 | public Bitmap call(Bitmap bitmap) {
70 | return BitmapUtil.blurBitmap(MainActivity.this, bitmap, 15.5f);
71 | }
72 | })
73 | .observeOn(AndroidSchedulers.mainThread())
74 | .subscribe(new Subscriber() {
75 | @Override
76 | public void onCompleted() {
77 | }
78 |
79 | @Override
80 | public void onError(Throwable e) {
81 | }
82 |
83 | @Override
84 | public void onNext(Bitmap bitmap) {
85 | mView.setAvator(bitmap);
86 | }
87 | });
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/ui/PersonalActivity.java:
--------------------------------------------------------------------------------
1 | package lico.example.ui;
2 |
3 | import android.view.MenuItem;
4 |
5 | import lico.example.presenter.ActivityPresenter;
6 | import lico.example.view.PersonalView;
7 |
8 | /**
9 | * Created by zzk on 15/11/28.
10 | */
11 | public class PersonalActivity extends ActivityPresenter{
12 |
13 | @Override
14 | public boolean onOptionsItemSelected(MenuItem item) {
15 | int id = item.getItemId();
16 | switch (id){
17 | case android.R.id.home:
18 | finish();
19 | return true;
20 | default:
21 | return super.onOptionsItemSelected(item);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/ui/SpaceImageDetailActivity.java:
--------------------------------------------------------------------------------
1 | package lico.example.ui;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ImageView;
8 |
9 | import com.bumptech.glide.Glide;
10 |
11 | import lico.example.views.SmoothImageView;
12 |
13 |
14 | /**
15 | * Created by zwl on 2015/8/20.
16 | * 单张图片点击详情activity
17 | */
18 | public class SpaceImageDetailActivity extends Activity {
19 | private String imgUrl;
20 | private int mPosition;
21 | private int mLocationX;
22 | private int mLocationY;
23 | private int mWidth;
24 | private int mHeight;
25 | SmoothImageView imageView = null;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | imgUrl = (String) getIntent().getSerializableExtra("images");
31 | mLocationX = getIntent().getIntExtra("locationX", 0);
32 | mLocationY = getIntent().getIntExtra("locationY", 0);
33 | mWidth = getIntent().getIntExtra("width", 0);
34 | mHeight = getIntent().getIntExtra("height", 0);
35 |
36 | imageView = new SmoothImageView(this);
37 | imageView.setOriginalInfo(mWidth, mHeight, mLocationX, mLocationY);
38 | imageView.transformIn();
39 | imageView.setLayoutParams(new ViewGroup.LayoutParams(-1, -1));
40 | imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
41 | setContentView(imageView);
42 | Glide.with(this).load(imgUrl)
43 | .crossFade().into((SmoothImageView) imageView);
44 | // ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 1.0f, 0.5f,
45 | // 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
46 | // 0.5f);
47 | // scaleAnimation.setDuration(300);
48 | // scaleAnimation.setInterpolator(new AccelerateInterpolator());
49 | // imageView.startAnimation(scaleAnimation);
50 | imageView.setOnClickListener(new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | outExit();
54 | }
55 | });
56 | }
57 |
58 | @Override
59 | public void onBackPressed() {
60 | outExit();
61 | }
62 |
63 | private void outExit(){
64 | imageView.setOnTransformListener(new SmoothImageView.TransformListener() {
65 | @Override
66 | public void onTransformComplete(int mode) {
67 | if (mode == 2) {
68 | finish();
69 | }
70 | }
71 | });
72 | imageView.transformOut();
73 | }
74 |
75 | @Override
76 | protected void onPause() {
77 | super.onPause();
78 | if (isFinishing()) {
79 | overridePendingTransition(0, 0);
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/utils/BitmapUtil.java:
--------------------------------------------------------------------------------
1 | package lico.example.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.ColorMatrix;
7 | import android.graphics.ColorMatrixColorFilter;
8 | import android.graphics.Paint;
9 | import android.graphics.drawable.BitmapDrawable;
10 | import android.graphics.drawable.Drawable;
11 | import android.renderscript.Allocation;
12 | import android.renderscript.Element;
13 | import android.renderscript.RenderScript;
14 | import android.renderscript.ScriptIntrinsicBlur;
15 |
16 | import lico.example.R;
17 |
18 | /**
19 | * Created by zzk on 15/11/28.
20 | */
21 | public class BitmapUtil {
22 |
23 | /**
24 | * 图片模糊效果
25 | */
26 | public static Bitmap blurBitmap(Context context, Bitmap bitmap, float radius){
27 | Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
28 | RenderScript rs = RenderScript.create(context);
29 |
30 | ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
31 |
32 | Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
33 | Allocation allOut = Allocation.createFromBitmap(rs, bitmap);
34 |
35 | blurScript.setRadius(radius);
36 |
37 | blurScript.setInput(allIn);
38 | blurScript.forEach(allOut);
39 |
40 | allOut.copyTo(outBitmap);
41 |
42 | bitmap.recycle();
43 | rs.destroy();
44 |
45 | return outBitmap;
46 | }
47 |
48 | /**
49 | * 图片黑白效果
50 | */
51 | public static Bitmap matrixBitmap(Context context, int drawableId){
52 | Drawable drawable = context.getResources().getDrawable(R.mipmap.avator);
53 | Bitmap srcBitmap = BitmapUtil.drawableToBitmap(drawable);
54 | float[] src = new float[]{
55 | 0.28F, 0.60F, 0.40F, 0, 0,
56 | 0.28F, 0.60F, 0.40F, 0, 0,
57 | 0.28F, 0.60F, 0.40F, 0, 0,
58 | 0, 0, 0, 1, 0,
59 | };
60 | ColorMatrix cm = new ColorMatrix(src);
61 | ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
62 | Bitmap resultBitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
63 | Bitmap.Config.ARGB_8888);
64 | Canvas canvas = new Canvas(resultBitmap );
65 | Paint paint = new Paint();
66 | paint.setAntiAlias(true);
67 | paint.setAlpha(100);
68 | paint.setColorFilter(f);
69 | canvas.drawBitmap(srcBitmap, 0, 0, paint);
70 | return resultBitmap;
71 | }
72 |
73 | /**
74 | * drawable转bitmap
75 | */
76 | public static Bitmap drawableToBitmap(Drawable drawable){
77 | Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
78 | return bitmap;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/utils/DataUtil.java:
--------------------------------------------------------------------------------
1 | package lico.example.utils;
2 |
3 |
4 | import org.jsoup.Jsoup;
5 | import org.jsoup.nodes.Document;
6 | import org.jsoup.nodes.Element;
7 | import org.jsoup.select.Elements;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | import lico.example.bean.JcodeInfo;
13 |
14 | /**
15 | * Created by zzk on 15/12/31.
16 | */
17 | public class DataUtil {
18 |
19 | public static List getJcodeData(String tid, int page) {
20 | List mList = new ArrayList<>();
21 | try {
22 | String url = "http://www.jcodecraeer.com/plus/list.php?tid=" + tid + "&TotalResult=1415&PageNo=" + page;
23 | Document doc = Jsoup.connect(url).get();
24 | Elements links = doc.select("div.archive-list-item");
25 | for (Element e : links) {
26 | JcodeInfo info = new JcodeInfo();
27 | info.detailUrl = e.select("a").attr("href");
28 | info.imageUrl = "http://www.jcodecraeer.com"+e.select("img").attr("src");
29 | info.title = e.select("div.post-intro").select("a[href]").attr("title");
30 | mList.add(info);
31 | }
32 | return mList;
33 | } catch (Exception e) {
34 | e.printStackTrace();
35 | }
36 | return null;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/ContentView.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.support.design.widget.TabLayout;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.view.ViewPager;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import butterknife.Bind;
11 | import lico.example.R;
12 | import lico.example.adapter.ContentPagerAdapter;
13 |
14 | /**
15 | * Created by zzk on 15/12/22.
16 | */
17 | public class ContentView extends ViewImpl {
18 | @Bind(R.id.content_tab)
19 | TabLayout tabs;
20 | @Bind(R.id.content_viewpager)
21 | ViewPager viewpager;
22 |
23 | private ContentPagerAdapter mPagerAdapter;
24 |
25 | @Override
26 | public int getLayoutId() {
27 | return R.layout.fragment_content;
28 | }
29 |
30 | public void initViewPager(String[] titles, String[] ids, FragmentManager fragmentManager) {
31 | viewpager.setOffscreenPageLimit(titles.length + 1);
32 | List tids = new ArrayList<>();
33 | List title = new ArrayList<>();
34 | for (String titles1 : titles) {
35 | title.add(titles1);
36 | }
37 | for (String id : ids) {
38 | tids.add(id);
39 | }
40 | mPagerAdapter = new ContentPagerAdapter(fragmentManager, title, tids);
41 | viewpager.setAdapter(mPagerAdapter);
42 | tabs.setupWithViewPager(viewpager);
43 | tabs.setTabsFromPagerAdapter(mPagerAdapter);
44 | }
45 |
46 | @Override
47 | public void destroy() {
48 |
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/ContentlistView.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import butterknife.Bind;
10 | import lico.example.R;
11 | import lico.example.adapter.BaseAdapterHelper;
12 | import lico.example.adapter.SimpleRecyclerAdapter;
13 | import lico.example.bean.JcodeInfo;
14 | import lico.example.views.PullLoadMoreRecyclerView;
15 |
16 | /**
17 | * Created by zzk on 15/12/22.
18 | */
19 | public class ContentListView extends ViewImpl {
20 |
21 | @Bind(R.id.pullloadmoreview)
22 | PullLoadMoreRecyclerView pullloadmoreview;
23 |
24 | private List mList = new ArrayList<>();
25 | private SimpleRecyclerAdapter mAdapter;
26 |
27 | @Override
28 | public int getLayoutId() {
29 | return R.layout.fragment_content_list;
30 | }
31 |
32 | public void initViews(Context context, PullLoadMoreRecyclerView.PullLoadMoreListener listener) {
33 | pullloadmoreview.setRefreshing(true);
34 | pullloadmoreview.setLinearLayout();
35 | pullloadmoreview.setOnPullLoadMoreListener(listener);
36 |
37 |
38 | mAdapter = new SimpleRecyclerAdapter(context, mList, R.layout.view_content_list) {
39 |
40 | @Override
41 | protected void convert(BaseAdapterHelper helper, JcodeInfo item) {
42 | helper.setText(R.id.content_text, item.title);
43 | helper.setImageByUrl(R.id.user_avator, item.imageUrl);
44 | }
45 | };
46 | pullloadmoreview.setAdapter(mAdapter);
47 | }
48 |
49 | public void refreshListData(List list) {
50 | mAdapter.getDataList().clear();
51 | mAdapter.getDataList().addAll(list);
52 | mAdapter.notifyDataSetChanged();
53 | pullloadmoreview.setPullLoadMoreCompleted();
54 | Log.e("x", "x getDataList : " + mAdapter.getDataList().size());
55 | }
56 |
57 | public void addListData(List list) {
58 | mAdapter.getDataList().addAll(list);
59 | mAdapter.notifyDataSetChanged();
60 | pullloadmoreview.setPullLoadMoreCompleted();
61 | }
62 |
63 | @Override
64 | public void destroy() {
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/IView.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.support.v7.widget.Toolbar;
8 |
9 | import lico.example.presenter.IPresenter;
10 |
11 | /**
12 | * Created by zzk on 15/11/26.
13 | */
14 | public interface IView {
15 |
16 | void create(LayoutInflater inflater, ViewGroup container);
17 |
18 | View getRootView();
19 |
20 | int getOptionsMenuId();
21 |
22 | Toolbar getToolbar();
23 |
24 | void bindPresenter(IPresenter presenter);
25 |
26 | void bindEvent();
27 |
28 | void destroy();
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/ImageListView.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.support.v7.widget.StaggeredGridLayoutManager;
7 | import android.view.View;
8 |
9 | import com.jcodecraeer.xrecyclerview.ProgressStyle;
10 | import com.jcodecraeer.xrecyclerview.XRecyclerView;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | import butterknife.Bind;
16 | import lico.example.R;
17 | import lico.example.adapter.BaseAdapterHelper;
18 | import lico.example.adapter.BaseQuickAdapter;
19 | import lico.example.adapter.SimpleRecyclerAdapter;
20 | import lico.example.bean.ImagesListEntity;
21 | import lico.example.ui.SpaceImageDetailActivity;
22 | import lico.example.views.PLAImageView;
23 | import lico.example.views.SpacesItemDecoration;
24 |
25 | /**
26 | * Created by zzk on 15/12/7.
27 | */
28 | public class ImageListView extends ViewImpl {
29 | @Bind(R.id.xrecyclerView)
30 | XRecyclerView xrecyclerView;
31 |
32 | private SimpleRecyclerAdapter mAdapter;
33 | private List mList = new ArrayList<>();
34 |
35 | @Override
36 | public int getLayoutId() {
37 | return R.layout.fragment_image_list;
38 | }
39 |
40 | public void initViews(Context context, XRecyclerView.LoadingListener listener){
41 | StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
42 | xrecyclerView.setLayoutManager(layoutManager);
43 | xrecyclerView.setLoadingListener(listener);
44 | xrecyclerView.setRefreshProgressStyle(ProgressStyle.BallRotate);
45 | xrecyclerView.setLaodingMoreProgressStyle(ProgressStyle.BallRotate);
46 | xrecyclerView.addItemDecoration(new SpacesItemDecoration(5));
47 | //xrecyclerView.setArrowImageView(R.drawable.iconfont_downgrey);
48 | mAdapter = new SimpleRecyclerAdapter(context, mList, R.layout.view_image_list_item) {
49 |
50 | @Override
51 | protected void convert(BaseAdapterHelper helper, ImagesListEntity item) {
52 | int width = item.thumbnailWidth;
53 | int height = item.thumbnailHeight;
54 | PLAImageView plaImageView = (PLAImageView) helper.getImageView(R.id.item_image);
55 | plaImageView.setImageHeight(height);
56 | plaImageView.setImageWidth(width);
57 | // helper.setImage(R.id.item_image, item.thumbnailUrl);
58 | helper.setImageByUrl(R.id.item_image, item.thumbnailUrl);
59 | }
60 | };
61 |
62 | mAdapter.setOnInViewClickListener(R.id.root_layout, new BaseQuickAdapter.onInternalClickListenerImpl(){
63 | @Override
64 | public void OnClickListener(View parentV, View v, Integer position, ImagesListEntity values) {
65 | int[] location = new int[2];
66 | v.getLocationOnScreen(location);
67 | int width = v.getWidth();
68 | int height = v.getHeight();
69 | gotoDetail((Activity) context, position, values, location[0], location[1], width, height);
70 | }
71 | });
72 |
73 | xrecyclerView.setAdapter(mAdapter);
74 | }
75 |
76 | public void refreshListData(List imageEntity) {
77 | mAdapter.getDataList().clear();
78 | mAdapter.getDataList().addAll(imageEntity);
79 | mAdapter.notifyDataSetChanged();
80 | xrecyclerView.refreshComplete();
81 | xrecyclerView.scrollToPosition(0);
82 | }
83 |
84 | public void addListData(List imageEntity){
85 | xrecyclerView.loadMoreComplete();
86 | mAdapter.getDataList().addAll(imageEntity);
87 | //用notifyDataSetChanged();会出现花屏问题
88 | mAdapter.notifyItemRangeChanged(mAdapter.getDataList().size() - 10, 10);
89 | xrecyclerView.refreshComplete();
90 | }
91 |
92 | private void gotoDetail(Activity activity, int position, ImagesListEntity imagesListEntity, int x, int y, int width, int height){
93 | Intent intent = new Intent(activity, SpaceImageDetailActivity.class);
94 | intent.putExtra("images", imagesListEntity.imageUrl);
95 | intent.putExtra("locationX", x);
96 | intent.putExtra("locationY", y);
97 | intent.putExtra("width", width);
98 | intent.putExtra("height", height);
99 | activity.startActivity(intent);
100 | activity.overridePendingTransition(0, 0);
101 | }
102 |
103 | @Override
104 | public void destroy() {
105 |
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/ImagesView.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.support.design.widget.TabLayout;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.view.ViewPager;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import butterknife.Bind;
11 | import lico.example.R;
12 | import lico.example.adapter.TabFragmentPagerAdapter;
13 |
14 | /**
15 | * Created by zzk on 15/12/1.
16 | */
17 | public class ImagesView extends ViewImpl {
18 | @Bind(R.id.tabs)
19 | TabLayout tabs;
20 | @Bind(R.id.viewpager)
21 | ViewPager viewpager;
22 |
23 | private TabFragmentPagerAdapter mPagerAdapter;
24 |
25 | @Override
26 | public int getLayoutId() {
27 | return R.layout.fragment_images;
28 | }
29 |
30 | public void initViewPager(String[] titles, FragmentManager manager){
31 | viewpager.setOffscreenPageLimit(titles.length + 1);
32 | List title = new ArrayList<>();
33 | for (String titles1 : titles)
34 | title.add(titles1);
35 | mPagerAdapter = new TabFragmentPagerAdapter(manager, title, 1);
36 | viewpager.setAdapter(mPagerAdapter);
37 | tabs.setupWithViewPager(viewpager);
38 | tabs.setTabsFromPagerAdapter(mPagerAdapter);
39 | }
40 |
41 | @Override
42 | public void destroy() {
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/MainView.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.NavigationView;
7 | import android.support.design.widget.Snackbar;
8 | import android.support.v4.app.FragmentManager;
9 | import android.support.v4.app.FragmentTransaction;
10 | import android.support.v4.view.GravityCompat;
11 | import android.support.v4.widget.DrawerLayout;
12 | import android.support.v7.app.ActionBarDrawerToggle;
13 | import android.support.v7.widget.Toolbar;
14 | import android.view.View;
15 | import android.widget.ImageView;
16 |
17 | import butterknife.Bind;
18 | import butterknife.ButterKnife;
19 | import lico.example.R;
20 | import lico.example.fragment.ContentFragment;
21 | import lico.example.fragment.ImageFragment;
22 | import lico.example.helper.EventHelper;
23 |
24 | /**
25 | * Created by zzk on 15/11/26.
26 | */
27 | public class MainView extends ViewImpl {
28 | @Bind(R.id.toolbar)
29 | Toolbar toolbar;
30 | @Bind(R.id.fab)
31 | FloatingActionButton fab;
32 | @Bind(R.id.nav_view)
33 | NavigationView navView;
34 | @Bind(R.id.drawer_layout)
35 | DrawerLayout drawerLayout;
36 |
37 |
38 | private ImageView mHeadBgImg, mAvatorImg;
39 | private ImageFragment mImageFragment;
40 | private ContentFragment mContentFragment;
41 |
42 | @Override
43 | public int getLayoutId() {
44 | return R.layout.activity_main;
45 | }
46 |
47 | @Override
48 | public void bindEvent() {
49 | super.bindEvent();
50 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
51 | (Activity) mRootView.getContext(), drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
52 | drawerLayout.setDrawerListener(toggle);
53 | toggle.syncState();
54 |
55 | View headerView = navView.inflateHeaderView(R.layout.nav_header_main);
56 | mHeadBgImg = (ImageView) headerView.findViewById(R.id.head_image);
57 | mAvatorImg = (ImageView) headerView.findViewById(R.id.imageView);
58 |
59 | EventHelper.click(mPresenter, fab, mAvatorImg);
60 | EventHelper.setNavigationItemSelected(mPresenter, navView);
61 | }
62 |
63 | public void setAvator(Bitmap bitmap) {
64 | mHeadBgImg.setImageBitmap(bitmap);
65 | }
66 |
67 | public boolean setNavigationItemSelected(FragmentManager manager, int menuId) {
68 | boolean isConsume = false;
69 | setNewRootFragment(manager, menuId);
70 | drawerLayout.closeDrawer(GravityCompat.START);
71 | return isConsume;
72 | }
73 |
74 | public boolean setOptionsItemSelected(int itemId) {
75 | boolean isConsume = false;
76 | switch (itemId) {
77 | case R.id.action_settings:
78 | Snackbar.make(mRootView.getRootView(), "点击了Setting", Snackbar.LENGTH_SHORT).setAction("Action", null).show();
79 | isConsume = true;
80 | break;
81 | }
82 | return isConsume;
83 | }
84 |
85 | public boolean closeDrawer() {
86 | if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
87 | drawerLayout.closeDrawer(GravityCompat.START);
88 | return true;
89 | } else return false;
90 | }
91 |
92 | public void setFabClick(String string) {
93 | Snackbar.make(mRootView.getRootView(), string, Snackbar.LENGTH_SHORT).setAction("Action", null).show();
94 | }
95 |
96 | public int getOptionsMenuId() {
97 | return R.menu.main;
98 | }
99 |
100 | @Override
101 | public Toolbar getToolbar() {
102 | return toolbar;
103 | }
104 |
105 | @Override
106 | public void destroy() {
107 | ButterKnife.unbind(mRootView.getRootView());
108 | }
109 |
110 | private void setNewRootFragment(FragmentManager manager, int menuId) {
111 | FragmentTransaction transaction = manager.beginTransaction();
112 | hideFragment(transaction);
113 | switch (menuId) {
114 | case R.id.nav_camera:
115 | mImageFragment = (ImageFragment) manager.findFragmentByTag("images");
116 | if (mImageFragment == null) {
117 | mImageFragment = new ImageFragment();
118 | transaction.add(R.id.container, mImageFragment, "images");
119 | } else {
120 | transaction.show(mImageFragment);
121 | }
122 | break;
123 | case R.id.nav_gallery:
124 | mContentFragment = (ContentFragment) manager.findFragmentByTag("contentlist");
125 | if (mContentFragment == null) {
126 | mContentFragment = new ContentFragment();
127 | transaction.add(R.id.container, mContentFragment, "contentlist");
128 | } else {
129 | transaction.show(mContentFragment);
130 | }
131 | break;
132 | case R.id.nav_slideshow:
133 |
134 | break;
135 | case R.id.nav_manage:
136 | break;
137 | case R.id.nav_share:
138 | break;
139 | case R.id.nav_send:
140 | break;
141 | }
142 | transaction.commit();
143 | drawerLayout.closeDrawers();
144 | }
145 |
146 | private void hideFragment(FragmentTransaction transaction) {
147 | if (mImageFragment != null) {
148 | transaction.hide(mImageFragment);
149 | }
150 | if (mContentFragment != null) {
151 | transaction.hide(mContentFragment);
152 | }
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/PersonalView.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.graphics.Color;
4 | import android.support.design.widget.AppBarLayout;
5 | import android.support.design.widget.CollapsingToolbarLayout;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.support.v7.widget.Toolbar;
8 | import android.widget.ImageView;
9 |
10 | import butterknife.Bind;
11 | import lico.example.R;
12 |
13 | /**
14 | * Created by zzk on 15/11/28.
15 | */
16 | public class PersonalView extends ViewImpl {
17 | @Bind(R.id.backgroud)
18 | ImageView backgroud;
19 | @Bind(R.id.toolbar)
20 | Toolbar toolbar;
21 | @Bind(R.id.appbar)
22 | AppBarLayout appbar;
23 | @Bind(R.id.recyclerView)
24 | RecyclerView recyclerView;
25 | @Bind(R.id.collapsing_toolbar)
26 | CollapsingToolbarLayout collapsingToolbar;
27 |
28 | @Override
29 | public int getLayoutId() {
30 | return R.layout.activity_personal;
31 | }
32 |
33 | @Override
34 | public void bindEvent() {
35 | super.bindEvent();
36 | collapsingToolbar.setTitle("Lico");
37 | collapsingToolbar.setExpandedTitleColor(Color.WHITE);
38 | collapsingToolbar.setCollapsedTitleTextColor(Color.GREEN);
39 |
40 | }
41 |
42 | @Override
43 | public Toolbar getToolbar() {
44 | return toolbar;
45 | }
46 |
47 | @Override
48 | public void destroy() {
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/view/ViewImpl.java:
--------------------------------------------------------------------------------
1 | package lico.example.view;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.support.v7.widget.Toolbar;
7 |
8 | import butterknife.ButterKnife;
9 | import lico.example.presenter.IPresenter;
10 |
11 | /**
12 | * Created by zzk on 15/11/26.
13 | */
14 | public abstract class ViewImpl implements IView {
15 | protected View mRootView;
16 | protected IPresenter mPresenter;
17 |
18 | @Override
19 | public void create(LayoutInflater inflater, ViewGroup container) {
20 | mRootView = inflater.inflate(getLayoutId(), container, false);
21 | ButterKnife.bind(this, mRootView.getRootView());
22 | }
23 |
24 | @Override
25 | public View getRootView() { return mRootView; }
26 |
27 | @Override
28 | public int getOptionsMenuId() {
29 | return 0;
30 | }
31 |
32 | @Override
33 | public Toolbar getToolbar() { return null; }
34 |
35 | @Override
36 | public void bindPresenter(IPresenter presenter) { mPresenter = presenter; }
37 |
38 | @Override
39 | public void bindEvent() {}
40 |
41 | public abstract int getLayoutId();
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/views/PLAImageView.java:
--------------------------------------------------------------------------------
1 | package lico.example.views;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.drawable.Drawable;
6 | import android.util.AttributeSet;
7 | import android.view.View;
8 | import android.widget.ImageView;
9 | import android.widget.RelativeLayout;
10 |
11 | /**
12 | * This view will auto determine the width or height by determining if the
13 | * height or width is set and scale the other dimension depending on the images
14 | * dimension
15 | *
16 | * This view also contains an ImageChangeListener which calls changed(boolean
17 | * isEmpty) once a change has been made to the ImageView
18 | *
19 | * @author Maurycy Wojtowicz
20 | */
21 | public class PLAImageView extends ImageView {
22 | private Bitmap currentBitmap;
23 | private ImageChangeListener imageChangeListener;
24 | private boolean scaleToWidth = false; // this flag determines if should
25 | // measure height manually dependent
26 | // of width
27 |
28 | public PLAImageView(Context context) {
29 | super(context);
30 | init();
31 | }
32 |
33 | public PLAImageView(Context context, AttributeSet attrs, int defStyle) {
34 | super(context, attrs, defStyle);
35 | init();
36 | }
37 |
38 | public PLAImageView(Context context, AttributeSet attrs) {
39 | super(context, attrs);
40 | init();
41 | }
42 |
43 | private void init() {
44 | this.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
45 | }
46 |
47 | public void recycle() {
48 | setImageBitmap(null);
49 | if ((this.currentBitmap == null) || (this.currentBitmap.isRecycled()))
50 | return;
51 | this.currentBitmap.recycle();
52 | this.currentBitmap = null;
53 | }
54 |
55 | @Override
56 | public void setImageBitmap(Bitmap bm) {
57 | currentBitmap = bm;
58 | super.setImageBitmap(currentBitmap);
59 | if (imageChangeListener != null)
60 | imageChangeListener.changed((currentBitmap == null));
61 | }
62 |
63 | @Override
64 | public void setImageDrawable(Drawable d) {
65 | super.setImageDrawable(d);
66 | if (imageChangeListener != null)
67 | imageChangeListener.changed((d == null));
68 | }
69 |
70 | @Override
71 | public void setImageResource(int id) {
72 | super.setImageResource(id);
73 | }
74 |
75 | public interface ImageChangeListener {
76 | // a callback for when a change has been made to this imageView
77 | void changed(boolean isEmpty);
78 | }
79 |
80 | public ImageChangeListener getImageChangeListener() {
81 | return imageChangeListener;
82 | }
83 |
84 | public void setImageChangeListener(ImageChangeListener imageChangeListener) {
85 | this.imageChangeListener = imageChangeListener;
86 | }
87 |
88 | private int imageWidth;
89 | private int imageHeight;
90 |
91 | public void setImageWidth(int w) {
92 | imageWidth = w;
93 | }
94 |
95 | public void setImageHeight(int h) {
96 | imageHeight = h;
97 | }
98 |
99 | @Override
100 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
101 |
102 | int widthMode = View.MeasureSpec.getMode(widthMeasureSpec);
103 | int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
104 | int width = View.MeasureSpec.getSize(widthMeasureSpec);
105 | int height = View.MeasureSpec.getSize(heightMeasureSpec);
106 |
107 | /**
108 | * if both width and height are set scale width first. modify in future
109 | * if necessary
110 | */
111 |
112 | if (widthMode == View.MeasureSpec.EXACTLY || widthMode == View.MeasureSpec.AT_MOST) {
113 | scaleToWidth = true;
114 | } else if (heightMode == View.MeasureSpec.EXACTLY || heightMode == View.MeasureSpec.AT_MOST) {
115 | scaleToWidth = false;
116 | } else
117 | throw new IllegalStateException("width or height needs to be set to match_parent or a specific dimension");
118 |
119 | if (imageWidth == 0) {
120 | // nothing to measure
121 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
122 | return;
123 | } else {
124 | if (scaleToWidth) {
125 | int iw = imageWidth;
126 | int ih = imageHeight;
127 | int heightC = width * ih / iw;
128 | if (height > 0)
129 | if (heightC > height) {
130 | // dont let hegiht be greater then set max
131 | heightC = height;
132 | width = heightC * iw / ih;
133 | }
134 |
135 | this.setScaleType(ImageView.ScaleType.CENTER_CROP);
136 | setMeasuredDimension(width, heightC);
137 |
138 | } else {
139 | // need to scale to height instead
140 | int marg = 0;
141 | if (getParent() != null) {
142 | if (getParent().getParent() != null) {
143 | marg += ((RelativeLayout) getParent().getParent()).getPaddingTop();
144 | marg += ((RelativeLayout) getParent().getParent()).getPaddingBottom();
145 | }
146 | }
147 |
148 | int iw = imageWidth;
149 | int ih = imageHeight;
150 |
151 | width = height * iw / ih;
152 | height -= marg;
153 | setMeasuredDimension(width, height);
154 | }
155 |
156 | }
157 | }
158 |
159 | }
160 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/views/PullLoadMoreRecyclerView.java:
--------------------------------------------------------------------------------
1 | package lico.example.views;
2 |
3 | import android.content.Context;
4 | import android.support.v4.widget.SwipeRefreshLayout;
5 | import android.support.v7.widget.DefaultItemAnimator;
6 | import android.support.v7.widget.GridLayoutManager;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.support.v7.widget.StaggeredGridLayoutManager;
10 | import android.util.AttributeSet;
11 | import android.view.LayoutInflater;
12 | import android.view.MotionEvent;
13 | import android.view.View;
14 | import android.widget.LinearLayout;
15 |
16 | import lico.example.R;
17 |
18 | /**
19 | * Created by zzk on 15/12/22.
20 | */
21 | public class PullLoadMoreRecyclerView extends LinearLayout{
22 |
23 | private RecyclerView mRecyclerView;
24 | private SwipeRefreshLayout mSwipeRefreshLayout;
25 | private PullLoadMoreListener mPullLoadMoreListener;
26 | private boolean hasMore = true;
27 | private boolean isRefresh = false;
28 | private boolean isLoadMore = false;
29 | private Context mContext;
30 |
31 |
32 | public PullLoadMoreRecyclerView(Context context) {
33 | super(context);
34 | initView(context);
35 | }
36 |
37 | public PullLoadMoreRecyclerView(Context context, AttributeSet attrs) {
38 | super(context, attrs);
39 | initView(context);
40 | }
41 |
42 | private void initView(Context context){
43 | mContext = context;
44 | View view = LayoutInflater.from(context).inflate(R.layout.view_pull_load_more, null);
45 | mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refreshlayout);
46 | mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_dark, android.R.color.holo_blue_dark, android.R.color.holo_orange_dark);
47 | mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayoutOnRefresh(this));
48 |
49 | mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
50 | mRecyclerView.setVerticalScrollBarEnabled(true);
51 |
52 | mRecyclerView.setHasFixedSize(true);
53 | mRecyclerView.setItemAnimator(new DefaultItemAnimator());
54 | //mRecyclerView.addItemDecoration(new DividerItemDecoration(
55 | //getActivity(), DividerItemDecoration.HORIZONTAL_LIST));
56 | mRecyclerView.addOnScrollListener(new RecyclerViewOnScroll(this));
57 | //Solve IndexOutOfBoundsException exception
58 | mRecyclerView.setOnTouchListener(
59 | new View.OnTouchListener() {
60 | @Override
61 | public boolean onTouch(View v, MotionEvent event) {
62 | if (isRefresh) {
63 | return true;
64 | } else {
65 | return false;
66 | }
67 | }
68 | }
69 | );
70 | this.addView(view);
71 |
72 | }
73 |
74 | /**
75 | * LinearLayoutManager
76 | */
77 | public void setLinearLayout() {
78 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
79 | linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
80 | mRecyclerView.setLayoutManager(linearLayoutManager);
81 | }
82 |
83 | /**
84 | * GridLayoutManager
85 | */
86 |
87 | public void setGridLayout(int spanCount) {
88 |
89 | GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, spanCount);
90 | gridLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
91 | mRecyclerView.setLayoutManager(gridLayoutManager);
92 | }
93 |
94 |
95 | /**
96 | * StaggeredGridLayoutManager
97 | */
98 |
99 | public void setStaggeredGridLayout(int spanCount) {
100 | StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(spanCount, LinearLayoutManager.VERTICAL);
101 | mRecyclerView.setLayoutManager(staggeredGridLayoutManager);
102 | }
103 |
104 | public void setPullRefreshEnable(boolean enable) {
105 | mSwipeRefreshLayout.setEnabled(enable);
106 | }
107 |
108 | public boolean getPullRefreshEnable() {
109 | return mSwipeRefreshLayout.isEnabled();
110 | }
111 |
112 | public RecyclerView.LayoutManager getLayoutManager() {
113 | return mRecyclerView.getLayoutManager();
114 | }
115 |
116 |
117 | public void loadMore() {
118 | if (mPullLoadMoreListener != null && hasMore) {
119 | mPullLoadMoreListener.onLoadMore();
120 |
121 | }
122 | }
123 |
124 |
125 | public void setPullLoadMoreCompleted() {
126 | isRefresh = false;
127 | mSwipeRefreshLayout.setRefreshing(false);
128 |
129 | isLoadMore = false;
130 |
131 | }
132 |
133 | public void setRefreshing(final boolean isRefreshing) {
134 | mSwipeRefreshLayout.post(new Runnable() {
135 |
136 | @Override
137 | public void run() {
138 | mSwipeRefreshLayout.setRefreshing(isRefreshing);
139 | }
140 | });
141 |
142 | }
143 |
144 |
145 | public void setOnPullLoadMoreListener(PullLoadMoreListener listener) {
146 | mPullLoadMoreListener = listener;
147 | }
148 |
149 | public void refresh() {
150 | mRecyclerView.setVisibility(View.VISIBLE);
151 | if (mPullLoadMoreListener != null) {
152 | mPullLoadMoreListener.onRefresh();
153 | }
154 | }
155 |
156 | public void scrollToTop() {
157 | mRecyclerView.scrollToPosition(0);
158 | }
159 |
160 |
161 | public void setAdapter(RecyclerView.Adapter adapter) {
162 | if (adapter != null) {
163 | mRecyclerView.setAdapter(adapter);
164 | }
165 | }
166 |
167 | public boolean isLoadMore() {
168 | return isLoadMore;
169 | }
170 |
171 | public void setIsLoadMore(boolean isLoadMore) {
172 | this.isLoadMore = isLoadMore;
173 | }
174 |
175 | public boolean isRefresh() {
176 | return isRefresh;
177 | }
178 |
179 | public void setIsRefresh(boolean isRefresh) {
180 | this.isRefresh = isRefresh;
181 | }
182 |
183 | public boolean isHasMore() {
184 | return hasMore;
185 | }
186 |
187 | public void setHasMore(boolean hasMore) {
188 | this.hasMore = hasMore;
189 | }
190 |
191 | public interface PullLoadMoreListener {
192 | public void onRefresh();
193 |
194 | public void onLoadMore();
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/views/RecyclerViewOnScroll.java:
--------------------------------------------------------------------------------
1 | package lico.example.views;
2 |
3 | import android.support.v7.widget.GridLayoutManager;
4 | import android.support.v7.widget.LinearLayoutManager;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.support.v7.widget.StaggeredGridLayoutManager;
7 |
8 | /**
9 | * Created by zzk on 15/12/23.
10 | */
11 | public class RecyclerViewOnScroll extends RecyclerView.OnScrollListener {
12 | PullLoadMoreRecyclerView mPullLoadMoreRecyclerView;
13 |
14 | public RecyclerViewOnScroll(PullLoadMoreRecyclerView pullLoadMoreRecyclerView) {
15 | this.mPullLoadMoreRecyclerView = pullLoadMoreRecyclerView;
16 | }
17 |
18 | @Override
19 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
20 | super.onScrolled(recyclerView, dx, dy);
21 | int lastVisibleItem = 0;
22 | int firstVisibleItem = 0;
23 | RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
24 | int totalItemCount = layoutManager.getItemCount();
25 | if (layoutManager instanceof LinearLayoutManager) {
26 | LinearLayoutManager linearLayoutManager = ((LinearLayoutManager) layoutManager);
27 | lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
28 | firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
29 | } else if (layoutManager instanceof GridLayoutManager) {
30 | GridLayoutManager gridLayoutManager = ((GridLayoutManager) layoutManager);
31 | //Position to find the final item of the current LayoutManager
32 | lastVisibleItem = gridLayoutManager.findLastVisibleItemPosition();
33 | firstVisibleItem = gridLayoutManager.findFirstCompletelyVisibleItemPosition();
34 | } else if (layoutManager instanceof StaggeredGridLayoutManager) {
35 | StaggeredGridLayoutManager staggeredGridLayoutManager = ((StaggeredGridLayoutManager) layoutManager);
36 | // since may lead to the final item has more than one StaggeredGridLayoutManager the particularity of the so here that is an array
37 | // this array into an array of position and then take the maximum value that is the last show the position value
38 | int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
39 | staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
40 | lastVisibleItem = findMax(lastPositions);
41 | firstVisibleItem = staggeredGridLayoutManager.findFirstVisibleItemPositions(lastPositions)[0];
42 | }
43 | if (firstVisibleItem == 0) {
44 | if (!mPullLoadMoreRecyclerView.isLoadMore()) {
45 | mPullLoadMoreRecyclerView.setPullRefreshEnable(true);
46 | }
47 | } else {
48 | mPullLoadMoreRecyclerView.setPullRefreshEnable(false);
49 | }
50 |
51 | /**
52 | * Either horizontal or vertical
53 | */
54 | if (!mPullLoadMoreRecyclerView.isRefresh() && mPullLoadMoreRecyclerView.isHasMore() && (lastVisibleItem >= totalItemCount - 1)
55 | && !mPullLoadMoreRecyclerView.isLoadMore() && (dx > 0 || dy > 0)) {
56 | mPullLoadMoreRecyclerView.setIsLoadMore(true);
57 | mPullLoadMoreRecyclerView.loadMore();
58 | }
59 |
60 | }
61 | //To find the maximum value in the array
62 |
63 | private int findMax(int[] lastPositions) {
64 |
65 | int max = lastPositions[0];
66 | for (int value : lastPositions) {
67 | // int max = Math.max(lastPositions,value);
68 | if (value > max) {
69 | max = value;
70 | }
71 | }
72 | return max;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/views/SmoothImageView.java:
--------------------------------------------------------------------------------
1 | package lico.example.views;
2 |
3 | import android.animation.Animator;
4 | import android.animation.PropertyValuesHolder;
5 | import android.animation.ValueAnimator;
6 | import android.app.Activity;
7 | import android.content.Context;
8 | import android.graphics.Bitmap;
9 | import android.graphics.Canvas;
10 | import android.graphics.Matrix;
11 | import android.graphics.Paint;
12 | import android.graphics.Paint.Style;
13 | import android.graphics.drawable.BitmapDrawable;
14 | import android.util.AttributeSet;
15 | import android.util.Log;
16 | import android.view.animation.AccelerateDecelerateInterpolator;
17 | import android.widget.ImageView;
18 |
19 | import com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable;
20 |
21 | /**
22 | * 2d平滑变化的显示图片的ImageView
23 | * 仅限于用于:从一个ScaleType==CENTER_CROP的ImageView,切换到另一个ScaleType=
24 | * FIT_CENTER的ImageView,或者反之 (当然,得使用同样的图片最好)
25 | *
26 | * @author Dean Tao
27 | *
28 | */
29 | public class SmoothImageView extends ImageView {
30 |
31 | private static final int STATE_NORMAL = 0;
32 | private static final int STATE_TRANSFORM_IN = 1;
33 | private static final int STATE_TRANSFORM_OUT = 2;
34 | private int mOriginalWidth;
35 | private int mOriginalHeight;
36 | private int mOriginalLocationX;
37 | private int mOriginalLocationY;
38 | private int mState = STATE_NORMAL;
39 | private Matrix mSmoothMatrix;
40 | private Bitmap mBitmap;
41 | private boolean mTransformStart = false;
42 | private Transfrom mTransfrom;
43 |
44 | private Paint mPaint;
45 |
46 | public SmoothImageView(Context context) {
47 | super(context);
48 | init();
49 | }
50 |
51 | public SmoothImageView(Context context, AttributeSet attrs) {
52 | super(context, attrs);
53 | init();
54 | }
55 |
56 | public SmoothImageView(Context context, AttributeSet attrs, int defStyle) {
57 | super(context, attrs, defStyle);
58 | init();
59 | }
60 |
61 | private void init() {
62 | mSmoothMatrix = new Matrix();
63 | mPaint=new Paint();
64 | mPaint.setColor(mBgColor);
65 | mPaint.setStyle(Style.FILL);
66 | // setBackgroundColor(mBgColor);
67 | }
68 |
69 | public void setOriginalInfo(int width, int height, int locationX, int locationY) {
70 | mOriginalWidth = width;
71 | mOriginalHeight = height;
72 | mOriginalLocationX = locationX;
73 | mOriginalLocationY = locationY;
74 | // 因为是屏幕坐标,所以要转换为该视图内的坐标,因为我所用的该视图是MATCH_PARENT,所以不用定位该视图的位置,如果不是的话,还需要定位视图的位置,然后计算mOriginalLocationX和mOriginalLocationY
75 | mOriginalLocationY = mOriginalLocationY - getStatusBarHeight(getContext());
76 | }
77 |
78 | /**
79 | * 获取状态栏高度
80 | *
81 | * @return
82 | */
83 | public static int getStatusBarHeight(Context context) {
84 | Class> c = null;
85 | Object obj = null;
86 | java.lang.reflect.Field field = null;
87 | int x = 0;
88 | int statusBarHeight = 0;
89 | try {
90 | c = Class.forName("com.android.internal.R$dimen");
91 | obj = c.newInstance();
92 | field = c.getField("status_bar_height");
93 | x = Integer.parseInt(field.get(obj).toString());
94 | statusBarHeight = context.getResources().getDimensionPixelSize(x);
95 | return statusBarHeight;
96 | } catch (Exception e) {
97 | e.printStackTrace();
98 | }
99 | return statusBarHeight;
100 | }
101 |
102 | /**
103 | * 用于开始进入的方法。 调用此方前,需已经调用过setOriginalInfo
104 | */
105 | public void transformIn() {
106 | mState = STATE_TRANSFORM_IN;
107 | mTransformStart = true;
108 | invalidate();
109 | }
110 |
111 | /**
112 | * 用于开始退出的方法。 调用此方前,需已经调用过setOriginalInfo
113 | */
114 | public void transformOut() {
115 | mState = STATE_TRANSFORM_OUT;
116 | mTransformStart = true;
117 | invalidate();
118 | }
119 |
120 | private class Transfrom {
121 | float startScale;// 图片开始的缩放值
122 | float endScale;// 图片结束的缩放值
123 | float scale;// 属性ValueAnimator计算出来的值
124 | LocationSizeF startRect;// 开始的区域
125 | LocationSizeF endRect;// 结束的区域
126 | LocationSizeF rect;// 属性ValueAnimator计算出来的值
127 |
128 | void initStartIn() {
129 | scale = startScale;
130 | try {
131 | rect = (LocationSizeF) startRect.clone();
132 | } catch (CloneNotSupportedException e) {
133 | e.printStackTrace();
134 | }
135 | }
136 |
137 | void initStartOut() {
138 | scale = endScale;
139 | try {
140 | rect = (LocationSizeF) endRect.clone();
141 | } catch (CloneNotSupportedException e) {
142 | e.printStackTrace();
143 | }
144 | }
145 |
146 | }
147 |
148 | /**
149 | * 初始化进入的变量信息
150 | */
151 | private void initTransform() {
152 | if (getDrawable() == null) {
153 | return;
154 | }
155 | if (mBitmap == null || mBitmap.isRecycled()) {
156 | // mBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
157 | mBitmap = ((GlideBitmapDrawable)getDrawable()).getBitmap();
158 | }
159 | //防止mTransfrom重复的做同样的初始化
160 | if (mTransfrom != null) {
161 | return;
162 | }
163 | if (getWidth() == 0 || getHeight() == 0) {
164 | return;
165 | }
166 | mTransfrom = new Transfrom();
167 |
168 | /** 下面为缩放的计算 */
169 | /* 计算初始的缩放值,初始值因为是CENTR_CROP效果,所以要保证图片的宽和高至少1个能匹配原始的宽和高,另1个大于 */
170 | float xSScale = mOriginalWidth / ((float) mBitmap.getWidth());
171 | float ySScale = mOriginalHeight / ((float) mBitmap.getHeight());
172 | float startScale = xSScale > ySScale ? xSScale : ySScale;
173 | mTransfrom.startScale = startScale;
174 | /* 计算结束时候的缩放值,结束值因为要达到FIT_CENTER效果,所以要保证图片的宽和高至少1个能匹配原始的宽和高,另1个小于 */
175 | float xEScale = getWidth() / ((float) mBitmap.getWidth());
176 | float yEScale = getHeight() / ((float) mBitmap.getHeight());
177 | float endScale = xEScale < yEScale ? xEScale : yEScale;
178 | mTransfrom.endScale = endScale;
179 |
180 | /**
181 | * 下面计算Canvas Clip的范围,也就是图片的显示的范围,因为图片是慢慢变大,并且是等比例的,所以这个效果还需要裁减图片显示的区域
182 | * ,而显示区域的变化范围是在原始CENTER_CROP效果的范围区域
183 | * ,到最终的FIT_CENTER的范围之间的,区域我用LocationSizeF更好计算
184 | * ,他就包括左上顶点坐标,和宽高,最后转为Canvas裁减的Rect.
185 | */
186 | /* 开始区域 */
187 | mTransfrom.startRect = new LocationSizeF();
188 | mTransfrom.startRect.left = mOriginalLocationX;
189 | mTransfrom.startRect.top = mOriginalLocationY;
190 | mTransfrom.startRect.width = mOriginalWidth;
191 | mTransfrom.startRect.height = mOriginalHeight;
192 | /* 结束区域 */
193 | mTransfrom.endRect = new LocationSizeF();
194 | float bitmapEndWidth = mBitmap.getWidth() * mTransfrom.endScale;// 图片最终的宽度
195 | float bitmapEndHeight = mBitmap.getHeight() * mTransfrom.endScale;// 图片最终的宽度
196 | mTransfrom.endRect.left = (getWidth() - bitmapEndWidth) / 2;
197 | mTransfrom.endRect.top = (getHeight() - bitmapEndHeight) / 2;
198 | mTransfrom.endRect.width = bitmapEndWidth;
199 | mTransfrom.endRect.height = bitmapEndHeight;
200 |
201 | mTransfrom.rect = new LocationSizeF();
202 | }
203 |
204 | private class LocationSizeF implements Cloneable {
205 | float left;
206 | float top;
207 | float width;
208 | float height;
209 | @Override
210 | public String toString() {
211 | return "[left:"+left+" top:"+top+" width:"+width+" height:"+height+"]";
212 | }
213 |
214 | @Override
215 | public Object clone() throws CloneNotSupportedException {
216 | // TODO Auto-generated method stub
217 | return super.clone();
218 | }
219 |
220 | }
221 |
222 | /* 下面实现了CENTER_CROP的功能 的Matrix,在优化的过程中,已经不用了 */
223 | private void getCenterCropMatrix() {
224 | if (getDrawable() == null) {
225 | return;
226 | }
227 | if (mBitmap == null || mBitmap.isRecycled()) {
228 | mBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
229 | }
230 | /* 下面实现了CENTER_CROP的功能 */
231 | float xScale = mOriginalWidth / ((float) mBitmap.getWidth());
232 | float yScale = mOriginalHeight / ((float) mBitmap.getHeight());
233 | float scale = xScale > yScale ? xScale : yScale;
234 | mSmoothMatrix.reset();
235 | mSmoothMatrix.setScale(scale, scale);
236 | mSmoothMatrix.postTranslate(-(scale * mBitmap.getWidth() / 2 - mOriginalWidth / 2), -(scale * mBitmap.getHeight() / 2 - mOriginalHeight / 2));
237 | }
238 |
239 | private void getBmpMatrix() {
240 | if (getDrawable() == null) {
241 | return;
242 | }
243 | if (mTransfrom == null) {
244 | return;
245 | }
246 | if (mBitmap == null || mBitmap.isRecycled()) {
247 | mBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
248 | }
249 | /* 下面实现了CENTER_CROP的功能 */
250 | mSmoothMatrix.setScale(mTransfrom.scale, mTransfrom.scale);
251 | mSmoothMatrix.postTranslate(-(mTransfrom.scale * mBitmap.getWidth() / 2 - mTransfrom.rect.width / 2),
252 | -(mTransfrom.scale * mBitmap.getHeight() / 2 - mTransfrom.rect.height / 2));
253 | }
254 |
255 | @Override
256 | protected void onDraw(Canvas canvas) {
257 | if (getDrawable() == null) {
258 | return; // couldn't resolve the URI
259 | }
260 |
261 | if (mState == STATE_TRANSFORM_IN || mState == STATE_TRANSFORM_OUT) {
262 | if (mTransformStart) {
263 | initTransform();
264 | }
265 | if (mTransfrom == null) {
266 | super.onDraw(canvas);
267 | return;
268 | }
269 |
270 | if (mTransformStart) {
271 | if (mState == STATE_TRANSFORM_IN) {
272 | mTransfrom.initStartIn();
273 | } else {
274 | mTransfrom.initStartOut();
275 | }
276 | }
277 |
278 | if(mTransformStart){
279 | Log.d("Dean", "mTransfrom.startScale:" + mTransfrom.startScale);
280 | Log.d("Dean", "mTransfrom.startScale:" + mTransfrom.endScale);
281 | Log.d("Dean", "mTransfrom.scale:" + mTransfrom.scale);
282 | Log.d("Dean", "mTransfrom.startRect:" + mTransfrom.startRect.toString());
283 | Log.d("Dean", "mTransfrom.endRect:" + mTransfrom.endRect.toString());
284 | Log.d("Dean", "mTransfrom.rect:" + mTransfrom.rect.toString());
285 | }
286 |
287 | mPaint.setAlpha(mBgAlpha);
288 | canvas.drawPaint(mPaint);
289 |
290 | int saveCount = canvas.getSaveCount();
291 | canvas.save();
292 | // 先得到图片在此刻的图像Matrix矩阵
293 | getBmpMatrix();
294 | canvas.translate(mTransfrom.rect.left, mTransfrom.rect.top);
295 | canvas.clipRect(0, 0, mTransfrom.rect.width, mTransfrom.rect.height);
296 | canvas.concat(mSmoothMatrix);
297 | getDrawable().draw(canvas);
298 | canvas.restoreToCount(saveCount);
299 | if (mTransformStart) {
300 | mTransformStart=false;
301 | startTransform(mState);
302 | }
303 | } else {
304 | //当Transform In变化完成后,把背景改为黑色,使得Activity不透明
305 | mPaint.setAlpha(255);
306 | canvas.drawPaint(mPaint);
307 | super.onDraw(canvas);
308 | }
309 | }
310 |
311 | private void startTransform(final int state) {
312 | if (mTransfrom == null) {
313 | return;
314 | }
315 | ValueAnimator valueAnimator = new ValueAnimator();
316 | valueAnimator.setDuration(300);
317 | valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
318 | if (state == STATE_TRANSFORM_IN) {
319 | PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scale", mTransfrom.startScale, mTransfrom.endScale);
320 | PropertyValuesHolder leftHolder = PropertyValuesHolder.ofFloat("left", mTransfrom.startRect.left, mTransfrom.endRect.left);
321 | PropertyValuesHolder topHolder = PropertyValuesHolder.ofFloat("top", mTransfrom.startRect.top, mTransfrom.endRect.top);
322 | PropertyValuesHolder widthHolder = PropertyValuesHolder.ofFloat("width", mTransfrom.startRect.width, mTransfrom.endRect.width);
323 | PropertyValuesHolder heightHolder = PropertyValuesHolder.ofFloat("height", mTransfrom.startRect.height, mTransfrom.endRect.height);
324 | PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofInt("alpha", 0, 255);
325 | valueAnimator.setValues(scaleHolder, leftHolder, topHolder, widthHolder, heightHolder, alphaHolder);
326 | } else {
327 | PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scale", mTransfrom.endScale, mTransfrom.startScale);
328 | PropertyValuesHolder leftHolder = PropertyValuesHolder.ofFloat("left", mTransfrom.endRect.left, mTransfrom.startRect.left);
329 | PropertyValuesHolder topHolder = PropertyValuesHolder.ofFloat("top", mTransfrom.endRect.top, mTransfrom.startRect.top);
330 | PropertyValuesHolder widthHolder = PropertyValuesHolder.ofFloat("width", mTransfrom.endRect.width, mTransfrom.startRect.width);
331 | PropertyValuesHolder heightHolder = PropertyValuesHolder.ofFloat("height", mTransfrom.endRect.height, mTransfrom.startRect.height);
332 | PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofInt("alpha", 255, 0);
333 | valueAnimator.setValues(scaleHolder, leftHolder, topHolder, widthHolder, heightHolder, alphaHolder);
334 | }
335 |
336 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
337 | @Override
338 | public synchronized void onAnimationUpdate(ValueAnimator animation) {
339 | mTransfrom.scale = (Float) animation.getAnimatedValue("scale");
340 | mTransfrom.rect.left = (Float) animation.getAnimatedValue("left");
341 | mTransfrom.rect.top = (Float) animation.getAnimatedValue("top");
342 | mTransfrom.rect.width = (Float) animation.getAnimatedValue("width");
343 | mTransfrom.rect.height = (Float) animation.getAnimatedValue("height");
344 | mBgAlpha = (Integer) animation.getAnimatedValue("alpha");
345 | invalidate();
346 | ((Activity)getContext()).getWindow().getDecorView().invalidate();
347 | }
348 | });
349 | valueAnimator.addListener(new ValueAnimator.AnimatorListener() {
350 | @Override
351 | public void onAnimationStart(Animator animation) {
352 |
353 | }
354 |
355 | @Override
356 | public void onAnimationRepeat(Animator animation) {
357 |
358 | }
359 |
360 | @Override
361 | public void onAnimationEnd(Animator animation) {
362 | /*
363 | * 如果是进入的话,当然是希望最后停留在center_crop的区域。但是如果是out的话,就不应该是center_crop的位置了
364 | * , 而应该是最后变化的位置,因为但是out的时候,不回复视图是Normal,要不然会有一个突然闪动回去的bug
365 | */
366 | // TODO 这个可以根据实际需求来修改
367 | if (state == STATE_TRANSFORM_IN) {
368 | mState = STATE_NORMAL;
369 | }
370 | if (mTransformListener != null) {
371 | mTransformListener.onTransformComplete(state);
372 | }
373 | }
374 |
375 | @Override
376 | public void onAnimationCancel(Animator animation) {
377 |
378 | }
379 | });
380 | valueAnimator.start();
381 | }
382 |
383 | private final int mBgColor = 0xFF000000;
384 | private int mBgAlpha = 0;
385 |
386 | public void setOnTransformListener(TransformListener listener) {
387 | mTransformListener = listener;
388 | }
389 |
390 | private TransformListener mTransformListener;
391 |
392 | public static interface TransformListener {
393 | /**
394 | *
395 | * @param mode
396 | * STATE_TRANSFORM_IN 1 ,STATE_TRANSFORM_OUT 2
397 | */
398 | void onTransformComplete(int mode);// mode 1
399 | }
400 |
401 | }
402 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/views/SpacesItemDecoration.java:
--------------------------------------------------------------------------------
1 | package lico.example.views;
2 |
3 | import android.graphics.Rect;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.View;
6 |
7 | /**
8 | * Created by zzk on 15/12/28.
9 | */
10 | public class SpacesItemDecoration extends RecyclerView.ItemDecoration{
11 |
12 | private int space;
13 |
14 | public SpacesItemDecoration(int space) {
15 | this.space = space;
16 | }
17 |
18 | @Override
19 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
20 | outRect.left = space;
21 | outRect.right = space;
22 | outRect.bottom = space;
23 | if(parent.getChildAdapterPosition(view) == 0){
24 | outRect.top = space;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/views/SuperRecyclerView.java:
--------------------------------------------------------------------------------
1 | package lico.example.views;
2 |
3 | import android.content.Context;
4 | import android.support.v4.widget.SwipeRefreshLayout;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.AttributeSet;
7 | import android.view.LayoutInflater;
8 | import android.view.MotionEvent;
9 | import android.view.View;
10 | import android.widget.LinearLayout;
11 |
12 | import lico.example.R;
13 |
14 | /**
15 | * Created by zzk on 15/12/30.
16 | */
17 | public class SuperRecyclerView extends LinearLayout{
18 |
19 | private RecyclerView mRecyclerView;
20 | private SwipeRefreshLayout mSwipeRefreshLayout;
21 | private PullLoadMoreListener mLoadMoreListener;
22 | private boolean isRefresh = false;
23 | private Context mContext;
24 |
25 | public SuperRecyclerView(Context context) {
26 | super(context);
27 | init(context);
28 | }
29 |
30 | public SuperRecyclerView(Context context, AttributeSet attrs) {
31 | super(context, attrs);
32 | init(context);
33 | }
34 |
35 | private void init(Context context){
36 | mContext = context;
37 | View view = LayoutInflater.from(mContext).inflate(R.layout.view_pull_load_more, null);
38 |
39 | mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refreshlayout);
40 | mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_dark, android.R.color.holo_blue_dark, android.R.color.holo_orange_dark);
41 | // mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayoutOnRefresh(this));
42 |
43 | mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
44 | // mRecyclerView.addOnScrollListener(new RecyclerViewOnScroll(this));
45 |
46 | mRecyclerView.setOnTouchListener(
47 | new View.OnTouchListener() {
48 | @Override
49 | public boolean onTouch(View v, MotionEvent event) {
50 | if (isRefresh) {
51 | return true;
52 | } else {
53 | return false;
54 | }
55 | }
56 | }
57 | );
58 | this.addView(view);
59 | }
60 |
61 | public void refresh(){
62 | if(mLoadMoreListener != null){
63 | mLoadMoreListener.onRefresh();
64 | }
65 | }
66 |
67 | public void loadMore() {
68 | if (mLoadMoreListener != null) {
69 | mLoadMoreListener.onLoadMore();
70 |
71 | }
72 | }
73 |
74 | public interface PullLoadMoreListener {
75 | public void onRefresh();
76 |
77 | public void onLoadMore();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/lico/example/views/SwipeRefreshLayoutOnRefresh.java:
--------------------------------------------------------------------------------
1 | package lico.example.views;
2 |
3 | import android.support.v4.widget.SwipeRefreshLayout;
4 |
5 | /**
6 | * Created by zzk on 15/12/22.
7 | */
8 | public class SwipeRefreshLayoutOnRefresh implements SwipeRefreshLayout.OnRefreshListener {
9 | PullLoadMoreRecyclerView mPullLoadMoreRecyclerView;
10 |
11 | public SwipeRefreshLayoutOnRefresh(PullLoadMoreRecyclerView pullLoadMoreRecyclerView) {
12 | this.mPullLoadMoreRecyclerView = pullLoadMoreRecyclerView;
13 | }
14 |
15 | @Override
16 | public void onRefresh() {
17 | if (!mPullLoadMoreRecyclerView.isRefresh()) {
18 | mPullLoadMoreRecyclerView.setIsRefresh(true);
19 | mPullLoadMoreRecyclerView.refresh();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_camera.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_gallery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_manage.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_send.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_slideshow.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/activated_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selectable_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_personal.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
24 |
25 |
33 |
34 |
40 |
41 |
42 |
43 |
48 |
49 |
54 |
55 |
56 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
23 |
24 |
25 |
26 |
33 |
34 |
35 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_content_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_image_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_images.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
19 |
20 |
21 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
19 |
20 |
28 |
29 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_content_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
21 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_image_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_pull_load_more.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/avator.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-xhdpi/avator.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/bg_banner_dialog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-xhdpi/bg_banner_dialog.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_discuss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-xxhdpi/ic_discuss.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 | - 美女
20 | - 动漫
21 | - 明星
22 | - 汽车
23 | - 摄影
24 | - 美食
25 |
26 |
27 |
28 | - 程序设计
29 | - 安卓开发
30 | - 前端开发
31 | - IOS开发
32 | - 数据库
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 | #2d5d82
8 | #21425d
9 | #01bcd5
10 |
11 | #FF6347
12 | #F4511E
13 | #FF5722
14 |
15 | #795548
16 | #5D4037
17 | #795548
18 |
19 |
20 | #2196F3
21 | #1976D2
22 | #448AFF
23 |
24 | #607D8B
25 | #455A64
26 | #607D8B
27 |
28 | #FF9800
29 | #F57C00
30 | #FF9800
31 |
32 | #673AB7
33 | #512DA8
34 | #7C4DFF
35 |
36 | #E91E63
37 | #C2185B
38 | #FF5722
39 |
40 | #4CAF50
41 | #388E3C
42 | #4CAF50
43 |
44 | #212121
45 | #727272
46 |
47 | #ffbebebe
48 | #9E9E9E
49 | #FF080808
50 | #ffbebebe
51 | #FFEEEEEE
52 |
53 | #88EEEEEE
54 | @android:color/white
55 | @android:color/white
56 |
57 | #FFffffff
58 | #ff999999
59 | #3e802f
60 | #f4b400
61 | #427fed
62 | #b23424
63 |
64 |
65 | - @color/gplus_color_1
66 | - @color/gplus_color_2
67 | - @color/gplus_color_3
68 | - @color/gplus_color_4
69 |
70 |
71 | #E6FFFFFF
72 | #1AFFFFFF
73 |
74 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 160dp
5 |
6 | 16dp
7 | 16dp
8 | 16dp
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 | - @android:drawable/ic_menu_camera
3 | - @android:drawable/ic_menu_gallery
4 | - @android:drawable/ic_menu_slideshow
5 | - @android:drawable/ic_menu_manage
6 | - @android:drawable/ic_menu_share
7 | - @android:drawable/ic_menu_send
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MVPExample
3 |
4 | Open navigation drawer
5 | Close navigation drawer
6 |
7 | Settings
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
35 |
36 |
39 |
40 |
45 |
46 |
49 |
50 |
52 |
53 |
58 |
59 |
75 |
76 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/test/java/lico/example/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package lico.example;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | mavenCentral()
7 | }
8 |
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:1.3.0'
11 | classpath 'me.tatarka:gradle-retrolambda:3.2.4'
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | jcenter()
20 | mavenCentral()
21 | }
22 | }
23 |
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzkong/MVPExample/dfe591ab976120b811cb5bc792a4b6cd9045f6d2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------