├── .gitignore ├── README.md ├── app ├── .gitignore ├── KeyStore │ └── release.jks ├── build.gradle ├── objectbox-models │ ├── default.json │ └── default.json.bak ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── lai │ │ └── mtc │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── data.json │ │ └── jump_loader.json │ ├── java │ │ └── com │ │ │ └── lai │ │ │ └── mtc │ │ │ ├── MTC.java │ │ │ ├── MainActivity.java │ │ │ ├── TestMainActivity.java │ │ │ ├── api │ │ │ └── ComicApi.java │ │ │ ├── bean │ │ │ ├── ComicCategories.java │ │ │ ├── ComicListDetail.java │ │ │ ├── ComicListInfo.java │ │ │ ├── ComicPreView.java │ │ │ └── ComicTypeInfo.java │ │ │ ├── comm │ │ │ ├── ApiException.java │ │ │ ├── CommonAdapter.java │ │ │ ├── ExceptionEngine.java │ │ │ ├── HttpRxObserver.java │ │ │ ├── ImageAutoLoadScrollListener.java │ │ │ ├── OnItemTouchListener.java │ │ │ ├── Parameter.java │ │ │ ├── SpaceItemDecoration.java │ │ │ ├── dialog │ │ │ │ ├── CommDialog.java │ │ │ │ └── LoadingDialog.java │ │ │ └── widget │ │ │ │ ├── BookView.java │ │ │ │ ├── BookViewLayout.java │ │ │ │ ├── InterceptAppBarLayout.java │ │ │ │ ├── InterceptCoordinatorLayout.java │ │ │ │ ├── MotionEventRecyclerView.java │ │ │ │ ├── PreCacheLayoutManager.java │ │ │ │ └── TouchRecyclerView.java │ │ │ ├── dao │ │ │ ├── BaseDao.java │ │ │ ├── CollectionDao.java │ │ │ ├── RecordDao.java │ │ │ ├── SearchRecordDao.java │ │ │ └── bean │ │ │ │ ├── Group.java │ │ │ │ ├── MyCollection.java │ │ │ │ ├── Record.java │ │ │ │ └── SearchRecord.java │ │ │ ├── di │ │ │ ├── component │ │ │ │ └── AppComponent.java │ │ │ └── module │ │ │ │ ├── ApiModule.java │ │ │ │ ├── AppModule.java │ │ │ │ ├── BuildersModule.java │ │ │ │ ├── DaoModule.java │ │ │ │ └── NetModule.java │ │ │ └── mvp │ │ │ ├── base │ │ │ ├── IModel.java │ │ │ ├── IPresenter.java │ │ │ ├── IView.java │ │ │ └── impl │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── BaseFragment.java │ │ │ │ ├── BaseModel.java │ │ │ │ ├── BaseMvpActivity.java │ │ │ │ ├── BaseMvpFragment.java │ │ │ │ └── BasePresenter.java │ │ │ ├── contract │ │ │ ├── ComicsContract.java │ │ │ ├── ComicsListDetailContract.java │ │ │ ├── ComicsPreviewContract.java │ │ │ ├── ComicsSearchContract.java │ │ │ └── SimpleContract.java │ │ │ ├── http │ │ │ ├── JsonTest.java │ │ │ └── RetrofitHelper.java │ │ │ ├── presenter │ │ │ ├── ComicsListDetailPresenter.java │ │ │ ├── ComicsPresenter.java │ │ │ ├── ComicsPreviewPresenter.java │ │ │ ├── ComicsSearchPresenter.java │ │ │ └── SimplePresenter.java │ │ │ ├── scope │ │ │ ├── ActivityScope.java │ │ │ └── FragmentScope.java │ │ │ ├── ui │ │ │ ├── cartoon │ │ │ │ └── fragment │ │ │ │ │ └── CartoonMainFragment.java │ │ │ └── comics │ │ │ │ ├── activity │ │ │ │ ├── ComicListDetailActivity.java │ │ │ │ ├── ComicPreviewActivity.java │ │ │ │ └── ComicSearchActivity.java │ │ │ │ ├── adapter │ │ │ │ ├── ChapterAdapter.java │ │ │ │ ├── ChapterDetailAdapter.java │ │ │ │ ├── MultiNumberAdapter.java │ │ │ │ └── PreviewAdapter.java │ │ │ │ ├── dialog │ │ │ │ ├── ModuleDialog.java │ │ │ │ └── SearchDialog.java │ │ │ │ ├── fragment │ │ │ │ └── ComicsMainFragment.java │ │ │ │ └── pop │ │ │ │ └── WindowLightPop.java │ │ │ └── utlis │ │ │ ├── ActivityUtils.java │ │ │ ├── CommonUtil.java │ │ │ ├── DensityUtil.java │ │ │ ├── FragmentUtils.java │ │ │ ├── IPopMenu.java │ │ │ ├── KeyBoardUtils.java │ │ │ ├── ListUtils.java │ │ │ ├── PopupMenuUtil.java │ │ │ ├── Preconditions.java │ │ │ ├── RxUtlis.java │ │ │ ├── SPUtils.java │ │ │ ├── ScreenUtils.java │ │ │ ├── StringUtils.java │ │ │ ├── ViewUtils.java │ │ │ ├── glide │ │ │ ├── GlideCacheUtil.java │ │ │ ├── ImageUtils.java │ │ │ ├── MyAppGlideModule.java │ │ │ ├── RoundCornersTransformation.java │ │ │ └── UnsafeOkHttpClient.java │ │ │ └── share │ │ │ ├── ShareElementInfo.java │ │ │ └── ShareElementUtils.java │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_action_back.png │ │ ├── ic_action_clean.png │ │ ├── ic_brightness.png │ │ ├── ic_change.png │ │ ├── ic_label_outline_black_24dp.png │ │ ├── ic_menu.png │ │ ├── ic_module.png │ │ ├── ic_search.png │ │ └── ic_sort.png │ │ ├── drawable-mdpi │ │ ├── ic_action_back.png │ │ ├── ic_action_clean.png │ │ ├── ic_brightness.png │ │ ├── ic_change.png │ │ ├── ic_label_outline_black_24dp.png │ │ ├── ic_menu.png │ │ ├── ic_module.png │ │ ├── ic_search.png │ │ └── ic_sort.png │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable-xhdpi │ │ ├── ic_action_back.png │ │ ├── ic_action_clean.png │ │ ├── ic_brightness.png │ │ ├── ic_change.png │ │ ├── ic_dashboard_black_24dp.png │ │ ├── ic_label_outline_black_24dp.png │ │ ├── ic_line_weight_black_24dp.png │ │ ├── ic_menu.png │ │ ├── ic_module.png │ │ ├── ic_round.png │ │ ├── ic_search.png │ │ ├── ic_sort.png │ │ └── img_cover_default.9.png │ │ ├── drawable-xxhdpi │ │ ├── bg_shadow2.png │ │ ├── ic_action_back.png │ │ ├── ic_action_clean.png │ │ ├── ic_brightness.png │ │ ├── ic_change.png │ │ ├── ic_dashboard_black_24dp.png │ │ ├── ic_label_outline_black_24dp.png │ │ ├── ic_line_weight_black_24dp.png │ │ ├── ic_menu.png │ │ ├── ic_module.png │ │ ├── ic_search.png │ │ ├── ic_sort.png │ │ └── img_shelf_other.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_label_outline_black_24dp.png │ │ └── ic_label_outline_white_24dp.png │ │ ├── drawable │ │ ├── bg_item_1.xml │ │ ├── ic_launcher_background.xml │ │ ├── seek_thumb.xml │ │ ├── seekbar_progress_drawable.xml │ │ └── shape_pop_checkaddshelf_bg.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── base_title.xml │ │ ├── book_layout_item.xml │ │ ├── comic_activity_list_detail.xml │ │ ├── comic_activity_preview.xml │ │ ├── comic_activity_preview_bottom_menu.xml │ │ ├── comic_activity_preview_left_menu.xml │ │ ├── comic_activity_search.xml │ │ ├── comic_dialog_search.xml │ │ ├── comic_item_bottom.xml │ │ ├── comic_item_bottom2.xml │ │ ├── comic_item_detail_list.xml │ │ ├── comic_item_list.xml │ │ ├── comic_item_list2.xml │ │ ├── comic_item_main_list.xml │ │ ├── comic_item_preview.xml │ │ ├── comic_item_preview2.xml │ │ ├── comic_item_preview_left.xml │ │ ├── comic_item_search_list.xml │ │ ├── comm_loading.xml │ │ ├── comm_loadmore.xml │ │ ├── comm_recyclerview.xml │ │ ├── fragment_comics.xml │ │ ├── include_title.xml │ │ ├── include_title_search.xml │ │ ├── menu_title.xml │ │ ├── menu_title_like.xml │ │ ├── pop_module.xml │ │ ├── pop_windowlight.xml │ │ ├── test.xml │ │ └── test_activity.xml │ │ ├── menu │ │ ├── action_changes.xml │ │ ├── action_like_source.xml │ │ └── action_search.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_author.png │ │ ├── ic_lable.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── ic_tag.png │ │ └── ic_user.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_place_holder.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── lai │ └── mtc │ └── ExampleUnitTest.java ├── build.gradle ├── config.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot ├── Collection.png ├── des.png ├── des2.png ├── find.png ├── find2.png ├── home.png ├── home2.png ├── list.png └── search.png └── 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 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
13 | * http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0209/2452.html
14 | */
15 |
16 | public class PreCacheLayoutManager extends LinearLayoutManager {
17 |
18 | public int getExtraSpace() {
19 | return mExtraSpace;
20 | }
21 |
22 | private int mExtraSpace = 0;
23 |
24 |
25 | public PreCacheLayoutManager(Context context) {
26 | super(context);
27 | }
28 |
29 |
30 | public void setExtraSpace(int extraSpace) {
31 | mExtraSpace = extraSpace;
32 | }
33 |
34 | //getExtraLayoutSpace(),增加不可见View的缓存的空间
35 | @Override
36 | protected int getExtraLayoutSpace(RecyclerView.State state) {
37 | if (mExtraSpace > 0) {
38 | if (getOrientation() == LinearLayoutManager.HORIZONTAL) {
39 | return mExtraSpace * getWidth();
40 | } else {
41 | return mExtraSpace * getHeight();
42 | }
43 | }
44 | return 0;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lai/mtc/comm/widget/TouchRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.lai.mtc.comm.widget;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.AttributeSet;
7 | import android.view.MotionEvent;
8 | import android.view.ViewConfiguration;
9 |
10 | /**
11 | * @author Lai
12 | * @time 2018/1/29 21:40
13 | * @describe 触摸相关的RecyclerView.
14 | * 具体的作用:只要点击事件。滑动的话不算
15 | */
16 |
17 | public class TouchRecyclerView extends RecyclerView {
18 |
19 | private int touchSlop;
20 | private float startX = -1;
21 | private float startY = -1;
22 |
23 |
24 | public void setITouchCallBack(ITouchCallBack IMiddleCallBack) {
25 | mIMiddleCallBack = IMiddleCallBack;
26 | }
27 |
28 | private ITouchCallBack mIMiddleCallBack;
29 |
30 | public TouchRecyclerView(Context context) {
31 | this(context, null);
32 | }
33 |
34 | public TouchRecyclerView(Context context, @Nullable AttributeSet attrs) {
35 | this(context, attrs, 0);
36 | }
37 |
38 | public TouchRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
39 | super(context, attrs, defStyle);
40 | touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
41 |
42 | //addOnScrollListener(new ImageAutoLoadScrollListener());
43 | }
44 |
45 |
46 |
47 | @Override
48 | public boolean onTouchEvent(MotionEvent event) {
49 | int action = event.getAction();
50 | switch (action) {
51 | case MotionEvent.ACTION_DOWN:
52 | startX = event.getX();
53 | startY = event.getY();
54 | break;
55 | case MotionEvent.ACTION_UP:
56 | if (Math.abs(event.getX() - startX) > touchSlop)
57 | startX = -1;
58 | if (Math.abs(event.getY() - startY) > touchSlop)
59 | startX = -1;
60 |
61 | if (startX != -1) {
62 | if (mIMiddleCallBack != null)
63 | mIMiddleCallBack.click();
64 | }
65 | break;
66 | default:
67 | break;
68 | }
69 | return super.onTouchEvent(event);
70 | }
71 |
72 | public interface ITouchCallBack {
73 | void click();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lai/mtc/dao/BaseDao.java:
--------------------------------------------------------------------------------
1 | package com.lai.mtc.dao;
2 |
3 | import com.lai.mtc.MTC;
4 |
5 | import java.lang.reflect.ParameterizedType;
6 | import java.util.List;
7 |
8 | import io.objectbox.Box;
9 |
10 | /**
11 | * @author Lai
12 | * @time 2018/2/10 17:36
13 | * @describe 增删改查基类
14 | */
15 | public class BaseDao
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.lai.mtc.mvp.base;
17 |
18 | import android.app.Activity;
19 |
20 | import io.reactivex.Observable;
21 |
22 | /**
23 | * P层封装。
24 | * @param
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.lai.mtc.mvp.base;
17 |
18 | import android.support.v7.widget.Toolbar;
19 |
20 | import com.lai.mtc.comm.ApiException;
21 | import com.lai.mtc.comm.dialog.LoadingDialog;
22 | import com.trello.rxlifecycle2.LifecycleTransformer;
23 |
24 | /**
25 | * View层公共封装
26 | *
27 | * @see com.lai.mtc.mvp.presenter.SimplePresenter
28 | */
29 | public interface IView {
30 |
31 | /**
32 | * 显示加载
33 | */
34 | void showLoading();
35 |
36 | void showLoading(@LoadingDialog.MODE int mode);
37 |
38 | /**
39 | * 隐藏加载
40 | */
41 | void hideLoading();
42 |
43 | /**
44 | * 显示信息
45 | */
46 | void showMessage(String message);
47 |
48 | extends BaseActivity implements IView {
17 | //实例化P.桥梁,辅助activity和model之间的交互
18 | @Inject
19 | protected P mPresenter;
20 |
21 |
22 | @Override
23 | public void initData(Bundle savedInstanceState) {
24 | //和View绑定
25 | if (mPresenter != null) {
26 | mPresenter.attachView(this);
27 | }
28 | init(savedInstanceState);
29 | bindEvent();
30 | }
31 |
32 | protected void bindEvent(){
33 |
34 | }
35 |
36 | public abstract void init(Bundle savedInstanceState);
37 |
38 | @Override
39 | protected void onDestroy() {
40 | //把所有的数据销毁掉
41 | super.onDestroy();
42 | if (mPresenter != null)
43 | mPresenter.onDestroy();//释放资源
44 | this.mPresenter = null;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lai/mtc/mvp/base/impl/BaseMvpFragment.java:
--------------------------------------------------------------------------------
1 | package com.lai.mtc.mvp.base.impl;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.lai.mtc.mvp.base.IPresenter;
6 |
7 | import javax.inject.Inject;
8 |
9 | /**
10 | * @author Lai
11 | * @time 2017/9/1 9:53
12 | * @describe MVP Fragment 封装
13 | */
14 |
15 | public abstract class BaseMvpFragment extends BaseFragment {
16 |
17 | @Inject
18 | protected P mPresenter;
19 |
20 | @Override
21 | public void finishCreateView(Bundle state) {
22 | if (mPresenter != null) {
23 | mPresenter.attachView(this);
24 | }
25 | init(state);
26 | bindEvent();
27 | }
28 |
29 | public abstract void init(Bundle state);
30 |
31 | @Override
32 | public void onDestroy() {
33 | super.onDestroy();
34 | if (mPresenter != null) mPresenter.onDestroy();//释放资源
35 | this.mPresenter = null;
36 | }
37 |
38 | public void bindEvent() {
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lai/mtc/mvp/base/impl/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.lai.mtc.mvp.base.impl;
2 |
3 | import android.arch.lifecycle.Lifecycle;
4 | import android.arch.lifecycle.LifecycleObserver;
5 | import android.arch.lifecycle.LifecycleOwner;
6 | import android.arch.lifecycle.OnLifecycleEvent;
7 |
8 | import com.lai.mtc.comm.ExceptionEngine;
9 | import com.lai.mtc.mvp.base.IPresenter;
10 | import com.lai.mtc.mvp.base.IView;
11 |
12 | import io.reactivex.Observable;
13 | import io.reactivex.annotations.NonNull;
14 | import io.reactivex.functions.Function;
15 |
16 | /**
17 | * @author Lai
18 | * @time 2017/12/10 16:32
19 | * @describe 公共P层
20 | */
21 |
22 | public class BasePresenter