├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── github │ │ └── cyc │ │ └── wanandroid │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── cyc │ │ │ └── wanandroid │ │ │ ├── app │ │ │ ├── Constant.java │ │ │ ├── GlideImageLoader.java │ │ │ ├── Injection.java │ │ │ ├── MyAppGlideModule.java │ │ │ ├── NoProguard.java │ │ │ ├── ScrollToTop.java │ │ │ └── WanApplication.java │ │ │ ├── base │ │ │ ├── activity │ │ │ │ └── BaseActivity.java │ │ │ ├── adapter │ │ │ │ ├── BaseAdapter.java │ │ │ │ ├── BasePagerAdapter.java │ │ │ │ └── BaseTagAdapter.java │ │ │ ├── fragment │ │ │ │ ├── BaseFragment.java │ │ │ │ └── BaseLazyFragment.java │ │ │ ├── viewholder │ │ │ │ └── BaseViewHolder.java │ │ │ └── viewmodel │ │ │ │ ├── BaseItemViewModel.java │ │ │ │ └── BaseViewModel.java │ │ │ ├── behavior │ │ │ ├── BottomNavigationBehavior.java │ │ │ └── FloatingActionButtonBehavior.java │ │ │ ├── binding │ │ │ └── WanBindingAdapter.java │ │ │ ├── data │ │ │ ├── DataManager.java │ │ │ └── source │ │ │ │ ├── HttpDataSource.java │ │ │ │ └── IHttpDataSource.java │ │ │ ├── enums │ │ │ ├── LoadState.java │ │ │ └── RefreshState.java │ │ │ ├── http │ │ │ ├── HttpCode.java │ │ │ ├── RetrofitManager.java │ │ │ ├── api │ │ │ │ └── ApiService.java │ │ │ ├── base │ │ │ │ ├── BaseObserver.java │ │ │ │ └── ObserverX.java │ │ │ └── model │ │ │ │ ├── Article.java │ │ │ │ ├── ArticleList.java │ │ │ │ ├── Banner.java │ │ │ │ ├── Chapter.java │ │ │ │ ├── Navigation.java │ │ │ │ ├── Response.java │ │ │ │ └── Tag.java │ │ │ ├── module │ │ │ ├── details │ │ │ │ ├── activity │ │ │ │ │ └── DetailsActivity.java │ │ │ │ └── viewmodel │ │ │ │ │ └── DetailsViewModel.java │ │ │ ├── main │ │ │ │ ├── activity │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── SystemDetailsActivity.java │ │ │ │ ├── adapter │ │ │ │ │ ├── ArticleListAdapter.java │ │ │ │ │ ├── ArticleListPagerAdapter.java │ │ │ │ │ ├── NavigationListAdapter.java │ │ │ │ │ ├── NavigationTagAdapter.java │ │ │ │ │ ├── ProjectListAdapter.java │ │ │ │ │ ├── ProjectListPagerAdapter.java │ │ │ │ │ └── SystemListAdapter.java │ │ │ │ ├── fragment │ │ │ │ │ ├── ArticleListFragment.java │ │ │ │ │ ├── HomepageFragment.java │ │ │ │ │ ├── NavigationFragment.java │ │ │ │ │ ├── ProjectFragment.java │ │ │ │ │ ├── ProjectListFragment.java │ │ │ │ │ ├── SystemFragment.java │ │ │ │ │ └── WeChatFragment.java │ │ │ │ ├── model │ │ │ │ │ ├── BannerData.java │ │ │ │ │ └── HomepageData.java │ │ │ │ ├── viewholder │ │ │ │ │ ├── ArticleViewHolder.java │ │ │ │ │ ├── BannerViewHolder.java │ │ │ │ │ ├── NavigationViewHolder.java │ │ │ │ │ ├── ProjectViewHolder.java │ │ │ │ │ └── SystemViewHolder.java │ │ │ │ └── viewmodel │ │ │ │ │ ├── ArticleListViewModel.java │ │ │ │ │ ├── HomepageViewModel.java │ │ │ │ │ ├── MainViewModel.java │ │ │ │ │ ├── NavigationViewModel.java │ │ │ │ │ ├── ProjectListViewModel.java │ │ │ │ │ ├── ProjectViewModel.java │ │ │ │ │ ├── SystemViewModel.java │ │ │ │ │ ├── WeChatViewModel.java │ │ │ │ │ └── item │ │ │ │ │ ├── ArticleViewModel.java │ │ │ │ │ ├── BannerViewModel.java │ │ │ │ │ ├── NavigationViewModel.java │ │ │ │ │ ├── ProjectViewModel.java │ │ │ │ │ └── SystemViewModel.java │ │ │ └── splash │ │ │ │ ├── activity │ │ │ │ └── SplashActivity.java │ │ │ │ └── viewmodel │ │ │ │ └── SplashViewModel.java │ │ │ ├── navigator │ │ │ ├── DetailsNavigator.java │ │ │ ├── MainNavigator.java │ │ │ └── SystemDetailsNavigator.java │ │ │ └── utils │ │ │ ├── ResourceUtils.java │ │ │ ├── RxUtils.java │ │ │ ├── ToastUtils.java │ │ │ └── Utils.java │ └── res │ │ ├── color │ │ └── selector_bottom_nav_item_color.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── animated_rotate_loading.xml │ │ ├── ic_about.xml │ │ ├── ic_arrow_back.xml │ │ ├── ic_arrow_right.xml │ │ ├── ic_arrow_upward.xml │ │ ├── ic_error.xml │ │ ├── ic_homepage.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_menu.xml │ │ ├── ic_navigation.xml │ │ ├── ic_project.xml │ │ ├── ic_settings.xml │ │ ├── ic_system.xml │ │ ├── ic_timelapse.xml │ │ ├── ic_we_chat.xml │ │ ├── selector_navigation_tag.xml │ │ ├── shape_label_green.xml │ │ └── shape_label_red.xml │ │ ├── layout │ │ ├── activity_base.xml │ │ ├── activity_details.xml │ │ ├── activity_main.xml │ │ ├── activity_splash.xml │ │ ├── activity_system_details.xml │ │ ├── fragment_article_list.xml │ │ ├── fragment_base.xml │ │ ├── fragment_homepage.xml │ │ ├── fragment_navigation.xml │ │ ├── fragment_project.xml │ │ ├── fragment_project_list.xml │ │ ├── fragment_system.xml │ │ ├── fragment_we_chat.xml │ │ ├── item_article.xml │ │ ├── item_banner.xml │ │ ├── item_navigation.xml │ │ ├── item_project.xml │ │ ├── item_system.xml │ │ ├── view_load_error.xml │ │ ├── view_loading.xml │ │ ├── view_nav_header.xml │ │ ├── view_navigation_tag.xml │ │ ├── view_no_data.xml │ │ ├── view_no_network.xml │ │ └── view_toolbar.xml │ │ ├── menu │ │ ├── menu_bottom_nav.xml │ │ └── menu_drawer_nav.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ ├── strings_behavior.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── github │ └── cyc │ └── wanandroid │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── node_modules ├── conventional-commit-types │ ├── .npmignore │ ├── .travis.yml │ ├── README.md │ ├── index.json │ └── package.json ├── cz-conventional-changelog │ ├── .npmignore │ ├── .travis.yml │ ├── README.md │ ├── engine.js │ ├── index.js │ └── package.json ├── lodash.map │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── longest │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── right-pad │ ├── .npmignore │ ├── README.md │ ├── examples │ │ └── basic.js │ ├── package.json │ └── rightpad.js └── word-wrap │ ├── LICENSE │ ├── README.md │ ├── index.d.ts │ ├── index.js │ └── package.json ├── package-lock.json ├── package.json ├── screenshots ├── 01-Homepage.jpg ├── 02-System.jpg ├── 03-WeChat.jpg ├── 04-Navigation.jpg └── 05-Project.jpg └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea 3 | .gradle 4 | /local.properties 5 | /.idea/caches/build_file_checksums.ser 6 | /.idea/libraries 7 | /.idea/modules.xml 8 | /.idea/workspace.xml 9 | .DS_Store 10 | /build 11 | /captures 12 | .externalNativeBuild 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WanAndroid-Java 2 | 玩Android客户端 3 | 4 | ## 项目简介 5 | 一款基于玩Android开放API开发的玩Android客户端。整个项目采用MVVM + Retrofit + RxJava架构进行开发。 6 | 7 | ## 项目截图 8 | 9 |
10 | 11 | 12 |
13 | 14 | ## 项目版本 15 | 16 | ### v1.0.0 17 | 18 | * 基本功能 19 | 20 | ## 技术要点 21 | 22 | * 采用MVVM模式开发,视图操作和业务逻辑解耦 23 | * 采用DataBinding框架实现View与数据的绑定,View层做到极度简洁 24 | * 采用Lifecycle实现ViewModel的生命周期回调 25 | * 采用Retrofit + RxJava实现网络请求 26 | * 采用Glide实现图片加载 27 | 28 | ## 感谢 29 | 30 | ### API 31 | 32 | * [玩Android](https://www.wanandroid.com/) 33 | 34 | ### 开源库 35 | 36 | * [MVVM](https://github.com/googlesamples/android-architecture/tree/todo-mvvm-databinding/) 37 | * [OkHttp](https://github.com/square/okhttp) 38 | * [Retrofit](https://github.com/square/retrofit) 39 | * [RxJava](https://github.com/ReactiveX/RxJava) 40 | * [RxAndroid](https://github.com/ReactiveX/RxAndroid) 41 | * [Glide](https://github.com/bumptech/glide) 42 | * [Material design icons](https://github.com/google/material-design-icons) 43 | * [Commitizen](https://github.com/commitizen/cz-cli) 44 | * [LeakCanary](https://github.com/square/leakcanary) 45 | * [Logger](https://github.com/orhanobut/logger) 46 | * [MaterialRefreshLayout](https://github.com/android-cjj/Android-MaterialRefreshLayout) 47 | * [Banner](https://github.com/youth5201314/banner) 48 | * [AgentWeb](https://github.com/Justson/AgentWeb) 49 | * [VerticalTabLayout](https://github.com/qstumn/VerticalTabLayout) 50 | * [FlowLayout](https://github.com/hongyangAndroid/FlowLayout) 51 | 52 | ## 声明 53 | 本项目纯属学习交流使用。 54 | 55 | ## LICENSE 56 | 57 | Copyright (c) 2019-present, chongyucaiyan. 58 | 59 | Licensed under the Apache License, Version 2.0 (the "License"); 60 | you may not use this file except in compliance with the License. 61 | You may obtain a copy of the License at 62 | 63 | http://www.apache.org/licenses/LICENSE-2.0 64 | 65 | Unless required by applicable law or agreed to in writing, software 66 | distributed under the License is distributed on an "AS IS" BASIS, 67 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 68 | See the License for the specific language governing permissions and 69 | limitations under the License. -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/github/cyc/wanandroid/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.github.cyc.wanandroid", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/app/Constant.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.app; 2 | 3 | /** 4 | * 常量 5 | */ 6 | public interface Constant { 7 | 8 | String BASE_URL = "https://www.wanandroid.com/"; 9 | String ABOUT_URL = "https://github.com/chongyucaiyan/WanAndroid-Java"; 10 | 11 | String KEY_URL = "key_url"; 12 | String KEY_ID = "key_id"; 13 | String KEY_CHAPTER = "key_chapter"; 14 | 15 | long SPLASH_TIME = 2000; 16 | long EXIT_TIME = 2000; 17 | 18 | long TIMEOUT_CONNECT = 10; 19 | long TIMEOUT_READ = 10; 20 | long TIMEOUT_WRITE = 10; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/app/GlideImageLoader.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.app; 2 | 3 | import android.content.Context; 4 | import android.widget.ImageView; 5 | 6 | import com.youth.banner.loader.ImageLoader; 7 | 8 | /** 9 | * Glide图片加载器。供Banner控件使用 10 | */ 11 | public class GlideImageLoader extends ImageLoader { 12 | 13 | @Override 14 | public void displayImage(Context context, Object path, ImageView imageView) { 15 | GlideApp.with(context).load(path).into(imageView); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/app/Injection.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.app; 2 | 3 | import com.github.cyc.wanandroid.data.DataManager; 4 | import com.github.cyc.wanandroid.data.source.HttpDataSource; 5 | import com.github.cyc.wanandroid.http.RetrofitManager; 6 | import com.github.cyc.wanandroid.http.api.ApiService; 7 | 8 | /** 9 | * 依赖注入 10 | */ 11 | public final class Injection { 12 | 13 | private Injection() { 14 | 15 | } 16 | 17 | /** 18 | * 提供DataManager 19 | * 20 | * @return DataManager 21 | */ 22 | public static DataManager provideDataManager() { 23 | return DataManager.getInstance(HttpDataSource.getInstance(RetrofitManager.get().create(ApiService.class))); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/app/MyAppGlideModule.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.app; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | 6 | import com.bumptech.glide.GlideBuilder; 7 | import com.bumptech.glide.annotation.GlideModule; 8 | import com.bumptech.glide.load.DecodeFormat; 9 | import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory; 10 | import com.bumptech.glide.load.engine.cache.LruResourceCache; 11 | import com.bumptech.glide.module.AppGlideModule; 12 | import com.bumptech.glide.request.RequestOptions; 13 | 14 | /** 15 | * Glide模块。配置Glide 16 | */ 17 | @GlideModule 18 | public class MyAppGlideModule extends AppGlideModule { 19 | 20 | private static final long SIZE_MEMORY_CACHE = 1024 * 1024 * 20; 21 | private static final long SIZE_DISK_CACHE = 1024 * 1024 * 100; 22 | 23 | @Override 24 | public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) { 25 | builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_RGB_565)) 26 | .setMemoryCache(new LruResourceCache(SIZE_MEMORY_CACHE)) 27 | .setDiskCache(new InternalCacheDiskCacheFactory(context, SIZE_DISK_CACHE)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/app/NoProguard.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.app; 2 | 3 | /** 4 | * 实现该接口的类不混淆 5 | */ 6 | public interface NoProguard { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/app/ScrollToTop.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.app; 2 | 3 | /** 4 | * 滚动到顶部接口 5 | */ 6 | public interface ScrollToTop { 7 | 8 | /** 9 | * 滚动到顶部 10 | */ 11 | void scrollToTop(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/app/WanApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.app; 2 | 3 | import android.app.Application; 4 | import android.support.annotation.Nullable; 5 | 6 | import com.github.cyc.wanandroid.BuildConfig; 7 | import com.github.cyc.wanandroid.R; 8 | import com.orhanobut.logger.AndroidLogAdapter; 9 | import com.orhanobut.logger.FormatStrategy; 10 | import com.orhanobut.logger.Logger; 11 | import com.orhanobut.logger.PrettyFormatStrategy; 12 | import com.squareup.leakcanary.LeakCanary; 13 | import com.squareup.leakcanary.RefWatcher; 14 | 15 | public class WanApplication extends Application { 16 | 17 | private static WanApplication sWanApplication; 18 | 19 | private static RefWatcher sRefWatcher; 20 | 21 | @Override 22 | public void onCreate() { 23 | super.onCreate(); 24 | if (LeakCanary.isInAnalyzerProcess(this)) { 25 | // This process is dedicated to LeakCanary for heap analysis. 26 | // You should not init your app in this process. 27 | return; 28 | } 29 | 30 | sRefWatcher = LeakCanary.install(this); 31 | // Normal app init code... 32 | 33 | sWanApplication = this; 34 | 35 | initLogger(); 36 | } 37 | 38 | public static WanApplication getInstance() { 39 | return sWanApplication; 40 | } 41 | 42 | public static RefWatcher getRefWatcher() { 43 | return sRefWatcher; 44 | } 45 | 46 | private void initLogger() { 47 | FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder() 48 | .tag(getString(R.string.app_name)) 49 | .build(); 50 | 51 | Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy) { 52 | 53 | @Override 54 | public boolean isLoggable(int priority, @Nullable String tag) { 55 | return BuildConfig.DEBUG; 56 | } 57 | }); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/base/adapter/BaseAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.base.adapter; 2 | 3 | import android.databinding.ObservableList; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.RecyclerView; 6 | 7 | /** 8 | * Adapter的基类 9 | */ 10 | public abstract class BaseAdapter extends RecyclerView.Adapter { 11 | 12 | protected ObservableList mDataList; 13 | 14 | public BaseAdapter(@NonNull ObservableList dataList) { 15 | mDataList = dataList; 16 | initCallback(); 17 | } 18 | 19 | private void initCallback() { 20 | mDataList.addOnListChangedCallback(new ObservableList.OnListChangedCallback>() { 21 | 22 | @Override 23 | public void onChanged(ObservableList sender) { 24 | notifyDataSetChanged(); 25 | } 26 | 27 | @Override 28 | public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) { 29 | notifyItemRangeChanged(positionStart, itemCount); 30 | } 31 | 32 | @Override 33 | public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) { 34 | notifyItemRangeInserted(positionStart, itemCount); 35 | } 36 | 37 | @Override 38 | public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) { 39 | if (itemCount == 1) { 40 | notifyItemMoved(fromPosition, toPosition); 41 | } else { 42 | notifyDataSetChanged(); 43 | } 44 | } 45 | 46 | @Override 47 | public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) { 48 | notifyItemRangeRemoved(positionStart, itemCount); 49 | } 50 | }); 51 | } 52 | 53 | @Override 54 | public int getItemCount() { 55 | return mDataList != null ? mDataList.size() : 0; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/base/adapter/BasePagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.base.adapter; 2 | 3 | import android.support.v4.app.Fragment; 4 | import android.support.v4.app.FragmentManager; 5 | import android.support.v4.app.FragmentPagerAdapter; 6 | import android.util.SparseArray; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * PagerAdapter的基类 12 | */ 13 | public abstract class BasePagerAdapter extends FragmentPagerAdapter { 14 | 15 | protected SparseArray mFragmentMap = new SparseArray<>(); 16 | 17 | protected List mDataList; 18 | 19 | public BasePagerAdapter(FragmentManager fragmentManager) { 20 | super(fragmentManager); 21 | } 22 | 23 | @Override 24 | public int getCount() { 25 | return mDataList != null ? mDataList.size() : 0; 26 | } 27 | 28 | /** 29 | * 设置数据列表 30 | * 31 | * @param dataList 数据列表 32 | */ 33 | public void setDataList(List dataList) { 34 | mDataList = dataList; 35 | notifyDataSetChanged(); 36 | } 37 | 38 | /** 39 | * 释放缓存的Fragment 40 | */ 41 | public void release() { 42 | mFragmentMap.clear(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/base/adapter/BaseTagAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.base.adapter; 2 | 3 | import com.zhy.view.flowlayout.TagAdapter; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * TagAdapter的基类 10 | * 11 | * @param 数据类型 12 | */ 13 | public abstract class BaseTagAdapter extends TagAdapter { 14 | 15 | private List mDataList; 16 | 17 | public BaseTagAdapter() { 18 | super(new ArrayList<>()); 19 | } 20 | 21 | @Override 22 | public int getCount() { 23 | return mDataList != null ? mDataList.size() : 0; 24 | } 25 | 26 | @Override 27 | public T getItem(int position) { 28 | return mDataList.get(position); 29 | } 30 | 31 | /** 32 | * 设置数据列表 33 | * 34 | * @param dataList 数据列表 35 | */ 36 | public void setDataList(List dataList) { 37 | mDataList = dataList; 38 | notifyDataChanged(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/base/fragment/BaseLazyFragment.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.base.fragment; 2 | 3 | import android.databinding.ViewDataBinding; 4 | import android.os.Bundle; 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | import android.view.View; 8 | 9 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 10 | 11 | /** 12 | * 懒加载Fragment的基类 13 | * 14 | * @param data binding 15 | * @param view model 16 | */ 17 | public abstract class BaseLazyFragment 18 | extends BaseFragment { 19 | 20 | protected boolean mVisibleToUser; 21 | 22 | protected boolean mViewCreated; 23 | 24 | protected boolean mLazyLoaded; 25 | 26 | @Override 27 | public void setUserVisibleHint(boolean isVisibleToUser) { 28 | super.setUserVisibleHint(isVisibleToUser); 29 | mVisibleToUser = isVisibleToUser; 30 | lazyLoad(); 31 | } 32 | 33 | @Override 34 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 35 | super.onViewCreated(view, savedInstanceState); 36 | mViewCreated = true; 37 | lazyLoad(); 38 | } 39 | 40 | private void lazyLoad() { 41 | if (mVisibleToUser && mViewCreated && !mLazyLoaded) { 42 | mLazyLoaded = true; 43 | onLazyLoad(); 44 | } 45 | } 46 | 47 | /** 48 | * 懒加载数据 49 | */ 50 | protected abstract void onLazyLoad(); 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/base/viewholder/BaseViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.base.viewholder; 2 | 3 | import android.databinding.DataBindingUtil; 4 | import android.databinding.ViewDataBinding; 5 | import android.support.annotation.LayoutRes; 6 | import android.support.annotation.NonNull; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.ViewGroup; 10 | 11 | import com.github.cyc.wanandroid.base.viewmodel.BaseItemViewModel; 12 | 13 | /** 14 | * ViewHolder的基类 15 | * 16 | * @param data binding 17 | * @param view model 18 | */ 19 | public abstract class BaseViewHolder 20 | extends RecyclerView.ViewHolder { 21 | 22 | protected DB mDataBinding; 23 | 24 | protected VM mViewModel; 25 | 26 | public BaseViewHolder(@NonNull ViewGroup parent, @LayoutRes int layoutResId) { 27 | super(DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), layoutResId, 28 | parent, false).getRoot()); 29 | mDataBinding = DataBindingUtil.getBinding(itemView); 30 | 31 | initViewModel(); 32 | bindViewModel(); 33 | 34 | init(); 35 | } 36 | 37 | public VM getViewModel() { 38 | return mViewModel; 39 | } 40 | 41 | /** 42 | * 初始化ViewModel 43 | */ 44 | protected abstract void initViewModel(); 45 | 46 | /** 47 | * 绑定ViewModel 48 | */ 49 | protected abstract void bindViewModel(); 50 | 51 | /** 52 | * 初始化 53 | */ 54 | protected abstract void init(); 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/base/viewmodel/BaseItemViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.base.viewmodel; 2 | 3 | import android.databinding.BaseObservable; 4 | import android.databinding.ObservableField; 5 | import android.support.annotation.NonNull; 6 | 7 | /** 8 | * Item的ViewModel的基类 9 | * 10 | * @param 基础model的类型 11 | */ 12 | public abstract class BaseItemViewModel extends BaseObservable { 13 | 14 | public final ObservableField baseModel = new ObservableField<>(); 15 | 16 | /** 17 | * 获取基础model 18 | * 19 | * @return 基础model 20 | */ 21 | public T getBaseModel() { 22 | return baseModel.get(); 23 | } 24 | 25 | /** 26 | * 设置基础model 27 | * 28 | * @param t 基础model 29 | */ 30 | public void setBaseModel(T t) { 31 | baseModel.set(t); 32 | 33 | if (t != null) { 34 | setAllModel(t); 35 | } 36 | } 37 | 38 | /** 39 | * 设置所有的model。如果设置了基础model,那么会设置所有的model 40 | * 41 | * @param t 基础model 42 | */ 43 | protected abstract void setAllModel(@NonNull T t); 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/base/viewmodel/BaseViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.base.viewmodel; 2 | 3 | import android.arch.lifecycle.DefaultLifecycleObserver; 4 | import android.arch.lifecycle.LifecycleOwner; 5 | import android.databinding.BaseObservable; 6 | import android.databinding.Bindable; 7 | import android.databinding.ObservableField; 8 | import android.support.annotation.NonNull; 9 | 10 | import com.github.cyc.wanandroid.BR; 11 | import com.github.cyc.wanandroid.enums.LoadState; 12 | import com.github.cyc.wanandroid.enums.RefreshState; 13 | import com.orhanobut.logger.Logger; 14 | 15 | import io.reactivex.disposables.CompositeDisposable; 16 | import io.reactivex.disposables.Disposable; 17 | 18 | /** 19 | * ViewModel的基类 20 | */ 21 | public abstract class BaseViewModel extends BaseObservable implements DefaultLifecycleObserver { 22 | 23 | public final ObservableField loadState = new ObservableField<>(); 24 | 25 | // 因为设置相同的值也要通知改变,所以采用@Bindable的方式 26 | private RefreshState refreshState; 27 | 28 | private Boolean hasMore; 29 | 30 | private CompositeDisposable mCompositeDisposable; 31 | 32 | @Override 33 | public void onCreate(@NonNull LifecycleOwner owner) { 34 | Logger.i(getClass().getSimpleName()); 35 | } 36 | 37 | @Override 38 | public void onDestroy(@NonNull LifecycleOwner owner) { 39 | Logger.i(getClass().getSimpleName()); 40 | 41 | // 取消所有的订阅,避免内存泄露 42 | if (mCompositeDisposable != null) { 43 | mCompositeDisposable.clear(); 44 | } 45 | } 46 | 47 | /** 48 | * 获取加载状态 49 | * 50 | * @return 加载状态 51 | */ 52 | public LoadState getLoadState() { 53 | return loadState.get(); 54 | } 55 | 56 | @Bindable 57 | public RefreshState getRefreshState() { 58 | return refreshState; 59 | } 60 | 61 | /** 62 | * 设置RefreshLayout的刷新状态 63 | * 64 | * @param refreshState 刷新状态 65 | */ 66 | protected void setRefreshState(RefreshState refreshState) { 67 | this.refreshState = refreshState; 68 | notifyPropertyChanged(BR.refreshState); 69 | } 70 | 71 | @Bindable 72 | public Boolean getHasMore() { 73 | return hasMore; 74 | } 75 | 76 | /** 77 | * 设置RefreshLayout的加载更多 78 | * 79 | * @param hasMore true表示还有更多,false表示没有更多了 80 | */ 81 | protected void setHasMore(Boolean hasMore) { 82 | this.hasMore = hasMore; 83 | notifyPropertyChanged(BR.hasMore); 84 | } 85 | 86 | /** 87 | * 重新加载数据。没有网络,点击重试时回调 88 | */ 89 | public void reloadData() { 90 | 91 | } 92 | 93 | /** 94 | * 添加订阅事件 95 | * 96 | * @param disposable 订阅事件 97 | */ 98 | protected void addDisposable(Disposable disposable) { 99 | if (mCompositeDisposable == null) { 100 | mCompositeDisposable = new CompositeDisposable(); 101 | } 102 | mCompositeDisposable.add(disposable); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/behavior/BottomNavigationBehavior.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.behavior; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.content.Context; 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | import android.support.design.widget.CoordinatorLayout; 8 | import android.support.v4.view.ViewCompat; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | 12 | import com.github.cyc.wanandroid.app.NoProguard; 13 | 14 | /** 15 | * 底部导航的Behavior 16 | */ 17 | public class BottomNavigationBehavior extends CoordinatorLayout.Behavior implements NoProguard { 18 | 19 | private ObjectAnimator mAnimatorOut; 20 | 21 | private ObjectAnimator mAnimatorIn; 22 | 23 | public BottomNavigationBehavior(Context context, @Nullable AttributeSet attrs) { 24 | super(context, attrs); 25 | } 26 | 27 | @Override 28 | public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, 29 | @NonNull View directTargetChild, @NonNull View target, int axes, int type) { 30 | return axes == ViewCompat.SCROLL_AXIS_VERTICAL; 31 | } 32 | 33 | @Override 34 | public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, 35 | @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) { 36 | // 上滑隐藏底部导航,下滑显示底部导航 37 | if (dy > 0 && child.getTranslationY() == 0) { 38 | if (mAnimatorOut == null) { 39 | mAnimatorOut = ObjectAnimator.ofFloat(child, "translationY", 0, child.getHeight()) 40 | .setDuration(300); 41 | } 42 | 43 | if (!mAnimatorOut.isRunning()) { 44 | mAnimatorOut.start(); 45 | } 46 | } else if (dy < 0 && child.getTranslationY() == child.getHeight()) { 47 | if (mAnimatorIn == null) { 48 | mAnimatorIn = ObjectAnimator.ofFloat(child, "translationY", child.getHeight(), 0) 49 | .setDuration(300); 50 | } 51 | 52 | if (!mAnimatorIn.isRunning()) { 53 | mAnimatorIn.start(); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/behavior/FloatingActionButtonBehavior.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.behavior; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.support.design.widget.CoordinatorLayout; 7 | import android.support.design.widget.FloatingActionButton; 8 | import android.support.v4.view.ViewCompat; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | 12 | import com.github.cyc.wanandroid.app.NoProguard; 13 | 14 | /** 15 | * 悬浮按钮的Behavior 16 | */ 17 | public class FloatingActionButtonBehavior extends FloatingActionButton.Behavior implements NoProguard { 18 | 19 | public FloatingActionButtonBehavior(Context context, @Nullable AttributeSet attrs) { 20 | super(context, attrs); 21 | } 22 | 23 | @Override 24 | public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, 25 | @NonNull View directTargetChild, @NonNull View target, int axes, int type) { 26 | return axes == ViewCompat.SCROLL_AXIS_VERTICAL; 27 | } 28 | 29 | @SuppressWarnings("RestrictedApi") 30 | @Override 31 | public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, 32 | @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { 33 | // 上滑隐藏悬浮按钮,下滑显示悬浮按钮 34 | if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) { 35 | child.setVisibility(View.INVISIBLE); 36 | } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { 37 | child.show(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/data/DataManager.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.data; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.github.cyc.wanandroid.data.source.IHttpDataSource; 6 | import com.github.cyc.wanandroid.http.model.Article; 7 | import com.github.cyc.wanandroid.http.model.ArticleList; 8 | import com.github.cyc.wanandroid.http.model.Banner; 9 | import com.github.cyc.wanandroid.http.model.Chapter; 10 | import com.github.cyc.wanandroid.http.model.Navigation; 11 | import com.github.cyc.wanandroid.http.model.Response; 12 | 13 | import java.util.List; 14 | 15 | import io.reactivex.Observable; 16 | 17 | /** 18 | * 数据管理类 19 | */ 20 | public class DataManager implements IHttpDataSource { 21 | 22 | private static volatile DataManager sDataManager; 23 | 24 | private IHttpDataSource mHttpDataSource; 25 | 26 | private DataManager(@NonNull IHttpDataSource httpDataSource) { 27 | mHttpDataSource = httpDataSource; 28 | } 29 | 30 | public static DataManager getInstance(IHttpDataSource httpDataSource) { 31 | if (sDataManager == null) { 32 | synchronized (DataManager.class) { 33 | if (sDataManager == null) { 34 | sDataManager = new DataManager(httpDataSource); 35 | } 36 | } 37 | } 38 | 39 | return sDataManager; 40 | } 41 | 42 | @Override 43 | public Observable>> getBannerData() { 44 | return mHttpDataSource.getBannerData(); 45 | } 46 | 47 | @Override 48 | public Observable>> getTopArticleListData() { 49 | return mHttpDataSource.getTopArticleListData(); 50 | } 51 | 52 | @Override 53 | public Observable> getArticleListData(int pageNum) { 54 | return mHttpDataSource.getArticleListData(pageNum); 55 | } 56 | 57 | @Override 58 | public Observable>> getSystemListData() { 59 | return mHttpDataSource.getSystemListData(); 60 | } 61 | 62 | @Override 63 | public Observable>> getWeChatListData() { 64 | return mHttpDataSource.getWeChatListData(); 65 | } 66 | 67 | @Override 68 | public Observable> getWeChatArticleListData(int id, int pageNum) { 69 | return mHttpDataSource.getWeChatArticleListData(id, pageNum); 70 | } 71 | 72 | @Override 73 | public Observable>> getNavigationListData() { 74 | return mHttpDataSource.getNavigationListData(); 75 | } 76 | 77 | @Override 78 | public Observable>> getProjectListData() { 79 | return mHttpDataSource.getProjectListData(); 80 | } 81 | 82 | @Override 83 | public Observable> getProjectArticleListData(int id, int pageNum) { 84 | return mHttpDataSource.getWeChatArticleListData(id, pageNum); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/data/source/HttpDataSource.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.data.source; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.github.cyc.wanandroid.http.api.ApiService; 6 | import com.github.cyc.wanandroid.http.model.Article; 7 | import com.github.cyc.wanandroid.http.model.ArticleList; 8 | import com.github.cyc.wanandroid.http.model.Banner; 9 | import com.github.cyc.wanandroid.http.model.Chapter; 10 | import com.github.cyc.wanandroid.http.model.Navigation; 11 | import com.github.cyc.wanandroid.http.model.Response; 12 | 13 | import java.util.List; 14 | 15 | import io.reactivex.Observable; 16 | 17 | /** 18 | * 网络数据源的实现 19 | */ 20 | public class HttpDataSource implements IHttpDataSource { 21 | 22 | private static volatile HttpDataSource sHttpDataSource; 23 | 24 | private ApiService mApiService; 25 | 26 | private HttpDataSource(@NonNull ApiService apiService) { 27 | mApiService = apiService; 28 | } 29 | 30 | public static HttpDataSource getInstance(ApiService apiService) { 31 | if (sHttpDataSource == null) { 32 | synchronized (HttpDataSource.class) { 33 | if (sHttpDataSource == null) { 34 | sHttpDataSource = new HttpDataSource(apiService); 35 | } 36 | } 37 | } 38 | 39 | return sHttpDataSource; 40 | } 41 | 42 | @Override 43 | public Observable>> getBannerData() { 44 | return mApiService.getBannerData(); 45 | } 46 | 47 | @Override 48 | public Observable>> getTopArticleListData() { 49 | return mApiService.getTopArticleListData(); 50 | } 51 | 52 | @Override 53 | public Observable> getArticleListData(int pageNum) { 54 | return mApiService.getArticleListData(pageNum); 55 | } 56 | 57 | @Override 58 | public Observable>> getSystemListData() { 59 | return mApiService.getSystemListData(); 60 | } 61 | 62 | @Override 63 | public Observable>> getWeChatListData() { 64 | return mApiService.getWeChatListData(); 65 | } 66 | 67 | @Override 68 | public Observable> getWeChatArticleListData(int id, int pageNum) { 69 | return mApiService.getWeChatArticleListData(id, pageNum); 70 | } 71 | 72 | @Override 73 | public Observable>> getNavigationListData() { 74 | return mApiService.getNavigationListData(); 75 | } 76 | 77 | @Override 78 | public Observable>> getProjectListData() { 79 | return mApiService.getProjectListData(); 80 | } 81 | 82 | @Override 83 | public Observable> getProjectArticleListData(int id, int pageNum) { 84 | return mApiService.getWeChatArticleListData(id, pageNum); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/data/source/IHttpDataSource.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.data.source; 2 | 3 | import com.github.cyc.wanandroid.http.api.ApiService; 4 | 5 | /** 6 | * 网络数据源接口 7 | */ 8 | public interface IHttpDataSource extends ApiService { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/enums/LoadState.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.enums; 2 | 3 | /** 4 | * 加载状态 5 | */ 6 | public enum LoadState { 7 | 8 | /** 9 | * 加载中 10 | */ 11 | LOADING, 12 | 13 | /** 14 | * 没有网络 15 | */ 16 | NO_NETWORK, 17 | 18 | /** 19 | * 没有数据 20 | */ 21 | NO_DATA, 22 | 23 | /** 24 | * 加载出错 25 | */ 26 | ERROR, 27 | 28 | /** 29 | * 加载成功 30 | */ 31 | SUCCESS 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/enums/RefreshState.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.enums; 2 | 3 | /** 4 | * 刷新状态 5 | */ 6 | public enum RefreshState { 7 | 8 | /** 9 | * 刷新结束 10 | */ 11 | REFRESH_END, 12 | 13 | /** 14 | * 加载更多结束 15 | */ 16 | LOAD_MORE_END 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/HttpCode.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http; 2 | 3 | /** 4 | * HTTP码 5 | */ 6 | public interface HttpCode { 7 | 8 | /** 9 | * 成功 10 | */ 11 | int SUCCESS = 0; 12 | 13 | /** 14 | * 未知错误 15 | */ 16 | int ERROR_UNKNOWN = 1000; 17 | 18 | /** 19 | * HTTP错误 20 | */ 21 | int ERROR_HTTP = 1001; 22 | 23 | /** 24 | * 网络错误 25 | */ 26 | int ERROR_NETWORK = 1002; 27 | 28 | /** 29 | * 解析错误 30 | */ 31 | int ERROR_PARSE = 1003; 32 | 33 | /** 34 | * SSL错误 35 | */ 36 | int ERROR_SSL = 1004; 37 | 38 | /** 39 | * 登录失效,需要重新登录 40 | */ 41 | int ERROR_LOGIN_INVALID = -1001; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/RetrofitManager.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http; 2 | 3 | import com.github.cyc.wanandroid.BuildConfig; 4 | import com.github.cyc.wanandroid.app.Constant; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import okhttp3.OkHttpClient; 9 | import okhttp3.logging.HttpLoggingInterceptor; 10 | import retrofit2.Retrofit; 11 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; 12 | import retrofit2.converter.gson.GsonConverterFactory; 13 | 14 | /** 15 | * Retrofit管理类 16 | */ 17 | public class RetrofitManager { 18 | 19 | private static class RetrofitInstance { 20 | private static Retrofit sRetrofit = buildRetrofit(); 21 | } 22 | 23 | private RetrofitManager() { 24 | 25 | } 26 | 27 | public static Retrofit get() { 28 | return RetrofitInstance.sRetrofit; 29 | } 30 | 31 | private static Retrofit buildRetrofit() { 32 | HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(); 33 | httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? 34 | HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE); 35 | 36 | OkHttpClient okHttpClient = new OkHttpClient.Builder() 37 | .connectTimeout(Constant.TIMEOUT_CONNECT, TimeUnit.SECONDS) 38 | .readTimeout(Constant.TIMEOUT_READ, TimeUnit.SECONDS) 39 | .writeTimeout(Constant.TIMEOUT_WRITE, TimeUnit.SECONDS) 40 | .addInterceptor(httpLoggingInterceptor) 41 | .build(); 42 | 43 | return new Retrofit.Builder() 44 | .baseUrl(Constant.BASE_URL) 45 | .client(okHttpClient) 46 | .addConverterFactory(GsonConverterFactory.create()) 47 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 48 | .build(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/api/ApiService.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.api; 2 | 3 | import com.github.cyc.wanandroid.http.model.Article; 4 | import com.github.cyc.wanandroid.http.model.ArticleList; 5 | import com.github.cyc.wanandroid.http.model.Banner; 6 | import com.github.cyc.wanandroid.http.model.Chapter; 7 | import com.github.cyc.wanandroid.http.model.Navigation; 8 | import com.github.cyc.wanandroid.http.model.Response; 9 | 10 | import java.util.List; 11 | 12 | import io.reactivex.Observable; 13 | import retrofit2.http.GET; 14 | import retrofit2.http.Path; 15 | import retrofit2.http.Query; 16 | 17 | /** 18 | * 网络请求描述接口 19 | */ 20 | public interface ApiService { 21 | 22 | /** 23 | * 获取首页Banner数据 24 | * 25 | * @return Banner数据 26 | */ 27 | @GET("banner/json") 28 | Observable>> getBannerData(); 29 | 30 | /** 31 | * 获取首页置顶文章列表数据 32 | * 33 | * @return 置顶文章列表数据 34 | */ 35 | @GET("article/top/json") 36 | Observable>> getTopArticleListData(); 37 | 38 | /** 39 | * 获取首页文章列表数据 40 | * 41 | * @param pageNum 页数 42 | * @return 文章列表数据 43 | */ 44 | @GET("article/list/{pageNum}/json") 45 | Observable> getArticleListData(@Path("pageNum") int pageNum); 46 | 47 | /** 48 | * 获取体系列表数据 49 | * 50 | * @return 体系列表数据 51 | */ 52 | @GET("tree/json") 53 | Observable>> getSystemListData(); 54 | 55 | /** 56 | * 获取公众号列表数据 57 | * 58 | * @return 公众号列表数据 59 | */ 60 | @GET("wxarticle/chapters/json") 61 | Observable>> getWeChatListData(); 62 | 63 | /** 64 | * 获取某个公众号文章列表数据 65 | * 66 | * @param id 公众号ID 67 | * @param pageNum 页数 68 | * @return 公众号文章列表数据 69 | */ 70 | @GET("wxarticle/list/{id}/{pageNum}/json") 71 | Observable> getWeChatArticleListData(@Path("id") int id, @Path("pageNum") int pageNum); 72 | 73 | /** 74 | * 获取导航列表数据 75 | * 76 | * @return 导航列表数据 77 | */ 78 | @GET("navi/json") 79 | Observable>> getNavigationListData(); 80 | 81 | /** 82 | * 获取项目分类列表数据 83 | * 84 | * @return 项目分类列表数据 85 | */ 86 | @GET("project/tree/json") 87 | Observable>> getProjectListData(); 88 | 89 | /** 90 | * 获取某个项目分类文章列表数据 91 | * 92 | * @param id 项目分类ID 93 | * @param pageNum 页数 94 | * @return 项目分类文章列表数据 95 | */ 96 | @GET("project/list/{pageNum}/json") 97 | Observable> getProjectArticleListData(@Query("cid") int id, @Path("pageNum") int pageNum); 98 | 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/base/ObserverX.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.base; 2 | 3 | /** 4 | * 自定义的Observer 5 | */ 6 | public interface ObserverX { 7 | 8 | /** 9 | * 成功时回调 10 | * 11 | * @param t 具体的网络请求响应model 12 | */ 13 | void onNextX(T t); 14 | 15 | /** 16 | * 出错时回调。与onCompleteX()方法互斥 17 | * 18 | * @param errorCode 错误码 19 | * @param errorMsg 错误信息 20 | */ 21 | void onErrorX(int errorCode, String errorMsg); 22 | 23 | /** 24 | * 结束时回调。与onErrorX()方法互斥 25 | */ 26 | void onCompleteX(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/model/ArticleList.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.model; 2 | 3 | import com.github.cyc.wanandroid.app.NoProguard; 4 | 5 | import java.util.List; 6 | 7 | public class ArticleList implements NoProguard { 8 | 9 | private Integer curPage; 10 | private Integer offset; 11 | private Boolean over; 12 | private Integer pageCount; 13 | private Integer size; 14 | private Integer total; 15 | private List
datas; 16 | 17 | public Integer getCurPage() { 18 | return curPage; 19 | } 20 | 21 | public void setCurPage(Integer curPage) { 22 | this.curPage = curPage; 23 | } 24 | 25 | public Integer getOffset() { 26 | return offset; 27 | } 28 | 29 | public void setOffset(Integer offset) { 30 | this.offset = offset; 31 | } 32 | 33 | public Boolean isOver() { 34 | return over; 35 | } 36 | 37 | public void setOver(Boolean over) { 38 | this.over = over; 39 | } 40 | 41 | public Integer getPageCount() { 42 | return pageCount; 43 | } 44 | 45 | public void setPageCount(Integer pageCount) { 46 | this.pageCount = pageCount; 47 | } 48 | 49 | public Integer getSize() { 50 | return size; 51 | } 52 | 53 | public void setSize(Integer size) { 54 | this.size = size; 55 | } 56 | 57 | public Integer getTotal() { 58 | return total; 59 | } 60 | 61 | public void setTotal(Integer total) { 62 | this.total = total; 63 | } 64 | 65 | public List
getDatas() { 66 | return datas; 67 | } 68 | 69 | public void setDatas(List
datas) { 70 | this.datas = datas; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/model/Banner.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.model; 2 | 3 | import com.github.cyc.wanandroid.app.NoProguard; 4 | 5 | public class Banner implements NoProguard { 6 | 7 | private String desc; 8 | private Integer id; 9 | private String imagePath; 10 | private Integer isVisible; 11 | private Integer order; 12 | private String title; 13 | private Integer type; 14 | private String url; 15 | 16 | public String getDesc() { 17 | return desc; 18 | } 19 | 20 | public void setDesc(String desc) { 21 | this.desc = desc; 22 | } 23 | 24 | public Integer getId() { 25 | return id; 26 | } 27 | 28 | public void setId(Integer id) { 29 | this.id = id; 30 | } 31 | 32 | public String getImagePath() { 33 | return imagePath; 34 | } 35 | 36 | public void setImagePath(String imagePath) { 37 | this.imagePath = imagePath; 38 | } 39 | 40 | public Integer getIsVisible() { 41 | return isVisible; 42 | } 43 | 44 | public void setIsVisible(Integer isVisible) { 45 | this.isVisible = isVisible; 46 | } 47 | 48 | public Integer getOrder() { 49 | return order; 50 | } 51 | 52 | public void setOrder(Integer order) { 53 | this.order = order; 54 | } 55 | 56 | public String getTitle() { 57 | return title; 58 | } 59 | 60 | public void setTitle(String title) { 61 | this.title = title; 62 | } 63 | 64 | public Integer getType() { 65 | return type; 66 | } 67 | 68 | public void setType(Integer type) { 69 | this.type = type; 70 | } 71 | 72 | public String getUrl() { 73 | return url; 74 | } 75 | 76 | public void setUrl(String url) { 77 | this.url = url; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/model/Chapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.model; 2 | 3 | import com.github.cyc.wanandroid.app.NoProguard; 4 | 5 | import java.io.Serializable; 6 | import java.util.List; 7 | 8 | public class Chapter implements NoProguard, Serializable { 9 | 10 | private Integer courseId; 11 | private Integer id; 12 | private String name; 13 | private Integer order; 14 | private Integer parentChapterId; 15 | private Boolean userControlSetTop; 16 | private Integer visible; 17 | private List children; 18 | 19 | public Integer getCourseId() { 20 | return courseId; 21 | } 22 | 23 | public void setCourseId(Integer courseId) { 24 | this.courseId = courseId; 25 | } 26 | 27 | public Integer getId() { 28 | return id; 29 | } 30 | 31 | public void setId(Integer id) { 32 | this.id = id; 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public void setName(String name) { 40 | this.name = name; 41 | } 42 | 43 | public Integer getOrder() { 44 | return order; 45 | } 46 | 47 | public void setOrder(Integer order) { 48 | this.order = order; 49 | } 50 | 51 | public Integer getParentChapterId() { 52 | return parentChapterId; 53 | } 54 | 55 | public void setParentChapterId(Integer parentChapterId) { 56 | this.parentChapterId = parentChapterId; 57 | } 58 | 59 | public Boolean isUserControlSetTop() { 60 | return userControlSetTop; 61 | } 62 | 63 | public void setUserControlSetTop(Boolean userControlSetTop) { 64 | this.userControlSetTop = userControlSetTop; 65 | } 66 | 67 | public Integer getVisible() { 68 | return visible; 69 | } 70 | 71 | public void setVisible(Integer visible) { 72 | this.visible = visible; 73 | } 74 | 75 | public List getChildren() { 76 | return children; 77 | } 78 | 79 | public void setChildren(List children) { 80 | this.children = children; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/model/Navigation.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.model; 2 | 3 | import com.github.cyc.wanandroid.app.NoProguard; 4 | 5 | import java.util.List; 6 | 7 | public class Navigation implements NoProguard { 8 | 9 | private Integer cid; 10 | private String name; 11 | private List
articles; 12 | 13 | public Integer getCid() { 14 | return cid; 15 | } 16 | 17 | public void setCid(Integer cid) { 18 | this.cid = cid; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | public List
getArticles() { 30 | return articles; 31 | } 32 | 33 | public void setArticles(List
articles) { 34 | this.articles = articles; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/model/Response.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.model; 2 | 3 | import com.github.cyc.wanandroid.app.NoProguard; 4 | 5 | /** 6 | * 网络请求响应model 7 | * 8 | * @param 具体的响应model 9 | */ 10 | public class Response implements NoProguard { 11 | 12 | /** 13 | * 错误码。0表示成功,非0表示失败 14 | */ 15 | private Integer errorCode; 16 | 17 | /** 18 | * 错误信息 19 | */ 20 | private String errorMsg; 21 | 22 | /** 23 | * 具体的响应model 24 | */ 25 | private T data; 26 | 27 | public Integer getErrorCode() { 28 | return errorCode; 29 | } 30 | 31 | public void setErrorCode(Integer errorCode) { 32 | this.errorCode = errorCode; 33 | } 34 | 35 | public String getErrorMsg() { 36 | return errorMsg; 37 | } 38 | 39 | public void setErrorMsg(String errorMsg) { 40 | this.errorMsg = errorMsg; 41 | } 42 | 43 | public T getData() { 44 | return data; 45 | } 46 | 47 | public void setData(T data) { 48 | this.data = data; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/http/model/Tag.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.http.model; 2 | 3 | import com.github.cyc.wanandroid.app.NoProguard; 4 | 5 | public class Tag implements NoProguard { 6 | 7 | private String name; 8 | private String url; 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getUrl() { 19 | return url; 20 | } 21 | 22 | public void setUrl(String url) { 23 | this.url = url; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/details/viewmodel/DetailsViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.details.viewmodel; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 6 | import com.github.cyc.wanandroid.data.DataManager; 7 | 8 | /** 9 | * 详情页的ViewModel 10 | */ 11 | public class DetailsViewModel extends BaseViewModel { 12 | 13 | private DataManager mDataManager; 14 | 15 | public DetailsViewModel(@NonNull DataManager dataManager) { 16 | mDataManager = dataManager; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/adapter/ArticleListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.adapter; 2 | 3 | import android.databinding.ObservableList; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.ViewGroup; 7 | 8 | import com.github.cyc.wanandroid.base.adapter.BaseAdapter; 9 | import com.github.cyc.wanandroid.http.model.Article; 10 | import com.github.cyc.wanandroid.module.main.model.BannerData; 11 | import com.github.cyc.wanandroid.module.main.viewholder.ArticleViewHolder; 12 | import com.github.cyc.wanandroid.module.main.viewholder.BannerViewHolder; 13 | 14 | /** 15 | * 文章列表Adapter 16 | */ 17 | public class ArticleListAdapter extends BaseAdapter { 18 | 19 | private static final int VIEW_TYPE_ARTICLE = 1; 20 | private static final int VIEW_TYPE_BANNER = 2; 21 | 22 | public ArticleListAdapter(@NonNull ObservableList dataList) { 23 | super(dataList); 24 | } 25 | 26 | @NonNull 27 | @Override 28 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 29 | switch (viewType) { 30 | case VIEW_TYPE_ARTICLE: 31 | return new ArticleViewHolder(parent); 32 | 33 | case VIEW_TYPE_BANNER: 34 | return new BannerViewHolder(parent); 35 | 36 | default: 37 | return null; 38 | } 39 | } 40 | 41 | @Override 42 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { 43 | Object data = mDataList.get(position); 44 | int viewType = getItemViewType(position); 45 | switch (viewType) { 46 | case VIEW_TYPE_ARTICLE: 47 | ((ArticleViewHolder) holder).getViewModel().setBaseModel((Article) data); 48 | break; 49 | 50 | case VIEW_TYPE_BANNER: 51 | ((BannerViewHolder) holder).getViewModel().setBaseModel((BannerData) data); 52 | break; 53 | 54 | default: 55 | break; 56 | } 57 | } 58 | 59 | @Override 60 | public int getItemViewType(int position) { 61 | Object data = mDataList.get(position); 62 | if (data instanceof Article) { 63 | return VIEW_TYPE_ARTICLE; 64 | } else if (data instanceof BannerData) { 65 | return VIEW_TYPE_BANNER; 66 | } else { 67 | return super.getItemViewType(position); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/adapter/ArticleListPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.adapter; 2 | 3 | import android.support.annotation.Nullable; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentManager; 6 | 7 | import com.github.cyc.wanandroid.base.adapter.BasePagerAdapter; 8 | import com.github.cyc.wanandroid.http.model.Chapter; 9 | import com.github.cyc.wanandroid.module.main.fragment.ArticleListFragment; 10 | 11 | /** 12 | * 文章列表PagerAdapter 13 | */ 14 | public class ArticleListPagerAdapter extends BasePagerAdapter { 15 | 16 | public ArticleListPagerAdapter(FragmentManager fragmentManager) { 17 | super(fragmentManager); 18 | } 19 | 20 | @Override 21 | public Fragment getItem(int position) { 22 | Fragment fragment = mFragmentMap.get(position); 23 | if (fragment == null) { 24 | Chapter chapter = mDataList.get(position); 25 | fragment = ArticleListFragment.newInstance(chapter.getId()); 26 | mFragmentMap.put(position, fragment); 27 | } 28 | 29 | return fragment; 30 | } 31 | 32 | @Nullable 33 | @Override 34 | public CharSequence getPageTitle(int position) { 35 | Chapter chapter = mDataList.get(position); 36 | return chapter.getName(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/adapter/NavigationListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.adapter; 2 | 3 | import android.databinding.ObservableList; 4 | import android.support.annotation.NonNull; 5 | import android.view.ViewGroup; 6 | 7 | import com.github.cyc.wanandroid.base.adapter.BaseAdapter; 8 | import com.github.cyc.wanandroid.http.model.Navigation; 9 | import com.github.cyc.wanandroid.module.main.viewholder.NavigationViewHolder; 10 | 11 | /** 12 | * 导航列表Adapter 13 | */ 14 | public class NavigationListAdapter extends BaseAdapter { 15 | 16 | public NavigationListAdapter(@NonNull ObservableList dataList) { 17 | super(dataList); 18 | } 19 | 20 | @NonNull 21 | @Override 22 | public NavigationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 23 | return new NavigationViewHolder(parent); 24 | } 25 | 26 | @Override 27 | public void onBindViewHolder(@NonNull NavigationViewHolder holder, int position) { 28 | Object data = mDataList.get(position); 29 | holder.getViewModel().setBaseModel((Navigation) data); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/adapter/NavigationTagAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.adapter; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.View; 5 | import android.widget.TextView; 6 | 7 | import com.github.cyc.wanandroid.R; 8 | import com.github.cyc.wanandroid.base.adapter.BaseTagAdapter; 9 | import com.github.cyc.wanandroid.http.model.Article; 10 | import com.zhy.view.flowlayout.FlowLayout; 11 | 12 | /** 13 | * 导航TagAdapter 14 | */ 15 | public class NavigationTagAdapter extends BaseTagAdapter
{ 16 | 17 | @Override 18 | public View getView(FlowLayout parent, int position, Article article) { 19 | TextView tvTag = (TextView) LayoutInflater.from(parent.getContext()) 20 | .inflate(R.layout.view_navigation_tag, parent, false); 21 | tvTag.setText(article.getTitle()); 22 | 23 | return tvTag; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/adapter/ProjectListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.adapter; 2 | 3 | import android.databinding.ObservableList; 4 | import android.support.annotation.NonNull; 5 | import android.view.ViewGroup; 6 | 7 | import com.github.cyc.wanandroid.base.adapter.BaseAdapter; 8 | import com.github.cyc.wanandroid.http.model.Article; 9 | import com.github.cyc.wanandroid.module.main.viewholder.ProjectViewHolder; 10 | 11 | /** 12 | * 项目列表Adapter 13 | */ 14 | public class ProjectListAdapter extends BaseAdapter { 15 | 16 | public ProjectListAdapter(@NonNull ObservableList dataList) { 17 | super(dataList); 18 | } 19 | 20 | @NonNull 21 | @Override 22 | public ProjectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 23 | return new ProjectViewHolder(parent); 24 | } 25 | 26 | @Override 27 | public void onBindViewHolder(@NonNull ProjectViewHolder holder, int position) { 28 | Object data = mDataList.get(position); 29 | holder.getViewModel().setBaseModel((Article) data); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/adapter/ProjectListPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.adapter; 2 | 3 | import android.support.annotation.Nullable; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentManager; 6 | 7 | import com.github.cyc.wanandroid.base.adapter.BasePagerAdapter; 8 | import com.github.cyc.wanandroid.http.model.Chapter; 9 | import com.github.cyc.wanandroid.module.main.fragment.ProjectListFragment; 10 | 11 | /** 12 | * 项目列表PagerAdapter 13 | */ 14 | public class ProjectListPagerAdapter extends BasePagerAdapter { 15 | 16 | public ProjectListPagerAdapter(FragmentManager fragmentManager) { 17 | super(fragmentManager); 18 | } 19 | 20 | @Override 21 | public Fragment getItem(int position) { 22 | Fragment fragment = mFragmentMap.get(position); 23 | if (fragment == null) { 24 | Chapter chapter = mDataList.get(position); 25 | fragment = ProjectListFragment.newInstance(chapter.getId()); 26 | mFragmentMap.put(position, fragment); 27 | } 28 | 29 | return fragment; 30 | } 31 | 32 | @Nullable 33 | @Override 34 | public CharSequence getPageTitle(int position) { 35 | Chapter chapter = mDataList.get(position); 36 | return chapter.getName(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/adapter/SystemListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.adapter; 2 | 3 | import android.databinding.ObservableList; 4 | import android.support.annotation.NonNull; 5 | import android.view.ViewGroup; 6 | 7 | import com.github.cyc.wanandroid.base.adapter.BaseAdapter; 8 | import com.github.cyc.wanandroid.http.model.Chapter; 9 | import com.github.cyc.wanandroid.module.main.viewholder.SystemViewHolder; 10 | 11 | /** 12 | * 体系列表Adapter 13 | */ 14 | public class SystemListAdapter extends BaseAdapter { 15 | 16 | public SystemListAdapter(@NonNull ObservableList dataList) { 17 | super(dataList); 18 | } 19 | 20 | @NonNull 21 | @Override 22 | public SystemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 23 | return new SystemViewHolder(parent); 24 | } 25 | 26 | @Override 27 | public void onBindViewHolder(@NonNull SystemViewHolder holder, int position) { 28 | Object data = mDataList.get(position); 29 | holder.getViewModel().setBaseModel((Chapter) data); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/fragment/ArticleListFragment.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | 6 | import com.cjj.MaterialRefreshLayout; 7 | import com.cjj.MaterialRefreshListener; 8 | import com.github.cyc.wanandroid.R; 9 | import com.github.cyc.wanandroid.app.Constant; 10 | import com.github.cyc.wanandroid.app.Injection; 11 | import com.github.cyc.wanandroid.app.ScrollToTop; 12 | import com.github.cyc.wanandroid.base.fragment.BaseLazyFragment; 13 | import com.github.cyc.wanandroid.databinding.FragmentArticleListBinding; 14 | import com.github.cyc.wanandroid.module.main.adapter.ArticleListAdapter; 15 | import com.github.cyc.wanandroid.module.main.viewmodel.ArticleListViewModel; 16 | 17 | /** 18 | * 文章列表页 19 | */ 20 | public class ArticleListFragment extends BaseLazyFragment 21 | implements ScrollToTop { 22 | 23 | private int mId; 24 | 25 | public static ArticleListFragment newInstance(int id) { 26 | Bundle bundle = new Bundle(); 27 | bundle.putInt(Constant.KEY_ID, id); 28 | 29 | ArticleListFragment fragment = new ArticleListFragment(); 30 | fragment.setArguments(bundle); 31 | 32 | return fragment; 33 | } 34 | 35 | @Override 36 | protected void handleArguments(Bundle args) { 37 | mId = args.getInt(Constant.KEY_ID, -1); 38 | } 39 | 40 | @Override 41 | protected int getLayoutResId() { 42 | return R.layout.fragment_article_list; 43 | } 44 | 45 | @Override 46 | protected void initViewModel() { 47 | mViewModel = new ArticleListViewModel(Injection.provideDataManager()); 48 | mViewModel.setId(mId); 49 | } 50 | 51 | @Override 52 | protected void bindViewModel() { 53 | mDataBinding.setViewModel(mViewModel); 54 | } 55 | 56 | @Override 57 | protected void init() { 58 | initRefreshLayout(); 59 | initRecyclerView(); 60 | } 61 | 62 | @Override 63 | protected void onLazyLoad() { 64 | mViewModel.loadData(); 65 | } 66 | 67 | @Override 68 | protected boolean isSupportLoad() { 69 | return true; 70 | } 71 | 72 | private void initRefreshLayout() { 73 | mDataBinding.mrlRefreshLayout.setMaterialRefreshListener(new MaterialRefreshListener() { 74 | 75 | @Override 76 | public void onRefresh(MaterialRefreshLayout materialRefreshLayout) { 77 | mViewModel.refreshData(); 78 | } 79 | 80 | @Override 81 | public void onRefreshLoadMore(MaterialRefreshLayout materialRefreshLayout) { 82 | mViewModel.loadMoreData(); 83 | } 84 | }); 85 | } 86 | 87 | private void initRecyclerView() { 88 | mDataBinding.rvRecyclerView.setAdapter(new ArticleListAdapter(mViewModel.dataList)); 89 | mDataBinding.rvRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 90 | } 91 | 92 | @Override 93 | public void scrollToTop() { 94 | mDataBinding.rvRecyclerView.smoothScrollToPosition(0); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/fragment/HomepageFragment.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.fragment; 2 | 3 | import android.support.v7.widget.LinearLayoutManager; 4 | 5 | import com.cjj.MaterialRefreshLayout; 6 | import com.cjj.MaterialRefreshListener; 7 | import com.github.cyc.wanandroid.R; 8 | import com.github.cyc.wanandroid.app.Injection; 9 | import com.github.cyc.wanandroid.app.ScrollToTop; 10 | import com.github.cyc.wanandroid.base.fragment.BaseFragment; 11 | import com.github.cyc.wanandroid.databinding.FragmentHomepageBinding; 12 | import com.github.cyc.wanandroid.module.main.adapter.ArticleListAdapter; 13 | import com.github.cyc.wanandroid.module.main.viewmodel.HomepageViewModel; 14 | 15 | /** 16 | * 首页tab 17 | */ 18 | public class HomepageFragment extends BaseFragment 19 | implements ScrollToTop { 20 | 21 | public static HomepageFragment newInstance() { 22 | return new HomepageFragment(); 23 | } 24 | 25 | @Override 26 | protected int getLayoutResId() { 27 | return R.layout.fragment_homepage; 28 | } 29 | 30 | @Override 31 | protected void initViewModel() { 32 | mViewModel = new HomepageViewModel(Injection.provideDataManager()); 33 | } 34 | 35 | @Override 36 | protected void bindViewModel() { 37 | mDataBinding.setViewModel(mViewModel); 38 | } 39 | 40 | @Override 41 | protected void init() { 42 | initRefreshLayout(); 43 | initRecyclerView(); 44 | mViewModel.loadData(); 45 | } 46 | 47 | @Override 48 | protected boolean isSupportLoad() { 49 | return true; 50 | } 51 | 52 | private void initRefreshLayout() { 53 | mDataBinding.mrlRefreshLayout.setMaterialRefreshListener(new MaterialRefreshListener() { 54 | 55 | @Override 56 | public void onRefresh(MaterialRefreshLayout materialRefreshLayout) { 57 | mViewModel.refreshData(); 58 | } 59 | 60 | @Override 61 | public void onRefreshLoadMore(MaterialRefreshLayout materialRefreshLayout) { 62 | mViewModel.loadMoreData(); 63 | } 64 | }); 65 | } 66 | 67 | private void initRecyclerView() { 68 | mDataBinding.rvRecyclerView.setAdapter(new ArticleListAdapter(mViewModel.dataList)); 69 | mDataBinding.rvRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 70 | } 71 | 72 | @Override 73 | public void scrollToTop() { 74 | mDataBinding.rvRecyclerView.smoothScrollToPosition(0); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/fragment/ProjectFragment.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.fragment; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | import com.github.cyc.wanandroid.R; 6 | import com.github.cyc.wanandroid.app.Injection; 7 | import com.github.cyc.wanandroid.app.ScrollToTop; 8 | import com.github.cyc.wanandroid.base.fragment.BaseFragment; 9 | import com.github.cyc.wanandroid.databinding.FragmentProjectBinding; 10 | import com.github.cyc.wanandroid.module.main.adapter.ProjectListPagerAdapter; 11 | import com.github.cyc.wanandroid.module.main.viewmodel.ProjectViewModel; 12 | 13 | /** 14 | * 项目tab 15 | */ 16 | public class ProjectFragment extends BaseFragment 17 | implements ScrollToTop { 18 | 19 | private ProjectListPagerAdapter mPagerAdapter; 20 | 21 | public static ProjectFragment newInstance() { 22 | return new ProjectFragment(); 23 | } 24 | 25 | @Override 26 | protected int getLayoutResId() { 27 | return R.layout.fragment_project; 28 | } 29 | 30 | @Override 31 | protected void initViewModel() { 32 | mViewModel = new ProjectViewModel(Injection.provideDataManager()); 33 | } 34 | 35 | @Override 36 | protected void bindViewModel() { 37 | mDataBinding.setViewModel(mViewModel); 38 | } 39 | 40 | @Override 41 | protected void init() { 42 | initView(); 43 | mViewModel.loadData(); 44 | } 45 | 46 | @Override 47 | protected boolean isSupportLoad() { 48 | return true; 49 | } 50 | 51 | private void initView() { 52 | mPagerAdapter = new ProjectListPagerAdapter(getChildFragmentManager()); 53 | mDataBinding.vpViewPager.setAdapter(mPagerAdapter); 54 | mDataBinding.tlTabLayout.setupWithViewPager(mDataBinding.vpViewPager); 55 | } 56 | 57 | @Override 58 | public void scrollToTop() { 59 | Fragment fragment = mPagerAdapter.getItem(mDataBinding.vpViewPager.getCurrentItem()); 60 | if (fragment instanceof ScrollToTop) { 61 | ((ScrollToTop) fragment).scrollToTop(); 62 | } 63 | } 64 | 65 | @Override 66 | public void onDestroyView() { 67 | super.onDestroyView(); 68 | mPagerAdapter.release(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/fragment/ProjectListFragment.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | 6 | import com.cjj.MaterialRefreshLayout; 7 | import com.cjj.MaterialRefreshListener; 8 | import com.github.cyc.wanandroid.R; 9 | import com.github.cyc.wanandroid.app.Constant; 10 | import com.github.cyc.wanandroid.app.Injection; 11 | import com.github.cyc.wanandroid.app.ScrollToTop; 12 | import com.github.cyc.wanandroid.base.fragment.BaseLazyFragment; 13 | import com.github.cyc.wanandroid.databinding.FragmentProjectListBinding; 14 | import com.github.cyc.wanandroid.module.main.adapter.ProjectListAdapter; 15 | import com.github.cyc.wanandroid.module.main.viewmodel.ProjectListViewModel; 16 | 17 | /** 18 | * 项目列表页 19 | */ 20 | public class ProjectListFragment extends BaseLazyFragment 21 | implements ScrollToTop { 22 | 23 | private int mId; 24 | 25 | public static ProjectListFragment newInstance(int id) { 26 | Bundle bundle = new Bundle(); 27 | bundle.putInt(Constant.KEY_ID, id); 28 | 29 | ProjectListFragment fragment = new ProjectListFragment(); 30 | fragment.setArguments(bundle); 31 | 32 | return fragment; 33 | } 34 | 35 | @Override 36 | protected void handleArguments(Bundle args) { 37 | mId = args.getInt(Constant.KEY_ID, -1); 38 | } 39 | 40 | @Override 41 | protected int getLayoutResId() { 42 | return R.layout.fragment_project_list; 43 | } 44 | 45 | @Override 46 | protected void initViewModel() { 47 | mViewModel = new ProjectListViewModel(Injection.provideDataManager()); 48 | mViewModel.setId(mId); 49 | } 50 | 51 | @Override 52 | protected void bindViewModel() { 53 | mDataBinding.setViewModel(mViewModel); 54 | } 55 | 56 | @Override 57 | protected void init() { 58 | initRefreshLayout(); 59 | initRecyclerView(); 60 | } 61 | 62 | @Override 63 | protected void onLazyLoad() { 64 | mViewModel.loadData(); 65 | } 66 | 67 | @Override 68 | protected boolean isSupportLoad() { 69 | return true; 70 | } 71 | 72 | private void initRefreshLayout() { 73 | mDataBinding.mrlRefreshLayout.setMaterialRefreshListener(new MaterialRefreshListener() { 74 | 75 | @Override 76 | public void onRefresh(MaterialRefreshLayout materialRefreshLayout) { 77 | mViewModel.refreshData(); 78 | } 79 | 80 | @Override 81 | public void onRefreshLoadMore(MaterialRefreshLayout materialRefreshLayout) { 82 | mViewModel.loadMoreData(); 83 | } 84 | }); 85 | } 86 | 87 | private void initRecyclerView() { 88 | mDataBinding.rvRecyclerView.setAdapter(new ProjectListAdapter(mViewModel.dataList)); 89 | mDataBinding.rvRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 90 | } 91 | 92 | @Override 93 | public void scrollToTop() { 94 | mDataBinding.rvRecyclerView.smoothScrollToPosition(0); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/fragment/SystemFragment.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.fragment; 2 | 3 | import android.support.v7.widget.LinearLayoutManager; 4 | 5 | import com.cjj.MaterialRefreshLayout; 6 | import com.cjj.MaterialRefreshListener; 7 | import com.github.cyc.wanandroid.R; 8 | import com.github.cyc.wanandroid.app.Injection; 9 | import com.github.cyc.wanandroid.app.ScrollToTop; 10 | import com.github.cyc.wanandroid.base.fragment.BaseFragment; 11 | import com.github.cyc.wanandroid.databinding.FragmentSystemBinding; 12 | import com.github.cyc.wanandroid.module.main.adapter.SystemListAdapter; 13 | import com.github.cyc.wanandroid.module.main.viewmodel.SystemViewModel; 14 | 15 | /** 16 | * 体系tab 17 | */ 18 | public class SystemFragment extends BaseFragment 19 | implements ScrollToTop { 20 | 21 | public static SystemFragment newInstance() { 22 | return new SystemFragment(); 23 | } 24 | 25 | @Override 26 | protected int getLayoutResId() { 27 | return R.layout.fragment_system; 28 | } 29 | 30 | @Override 31 | protected void initViewModel() { 32 | mViewModel = new SystemViewModel(Injection.provideDataManager()); 33 | } 34 | 35 | @Override 36 | protected void bindViewModel() { 37 | mDataBinding.setViewModel(mViewModel); 38 | } 39 | 40 | @Override 41 | protected void init() { 42 | initRefreshLayout(); 43 | initRecyclerView(); 44 | mViewModel.loadData(); 45 | } 46 | 47 | @Override 48 | protected boolean isSupportLoad() { 49 | return true; 50 | } 51 | 52 | private void initRefreshLayout() { 53 | mDataBinding.mrlRefreshLayout.setMaterialRefreshListener(new MaterialRefreshListener() { 54 | 55 | @Override 56 | public void onRefresh(MaterialRefreshLayout materialRefreshLayout) { 57 | mViewModel.refreshData(); 58 | } 59 | }); 60 | } 61 | 62 | private void initRecyclerView() { 63 | mDataBinding.rvRecyclerView.setAdapter(new SystemListAdapter(mViewModel.dataList)); 64 | mDataBinding.rvRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 65 | } 66 | 67 | @Override 68 | public void scrollToTop() { 69 | mDataBinding.rvRecyclerView.smoothScrollToPosition(0); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/fragment/WeChatFragment.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.fragment; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | import com.github.cyc.wanandroid.R; 6 | import com.github.cyc.wanandroid.app.Injection; 7 | import com.github.cyc.wanandroid.app.ScrollToTop; 8 | import com.github.cyc.wanandroid.base.fragment.BaseFragment; 9 | import com.github.cyc.wanandroid.databinding.FragmentWeChatBinding; 10 | import com.github.cyc.wanandroid.module.main.adapter.ArticleListPagerAdapter; 11 | import com.github.cyc.wanandroid.module.main.viewmodel.WeChatViewModel; 12 | 13 | /** 14 | * 公众号tab 15 | */ 16 | public class WeChatFragment extends BaseFragment 17 | implements ScrollToTop { 18 | 19 | private ArticleListPagerAdapter mPagerAdapter; 20 | 21 | public static WeChatFragment newInstance() { 22 | return new WeChatFragment(); 23 | } 24 | 25 | @Override 26 | protected int getLayoutResId() { 27 | return R.layout.fragment_we_chat; 28 | } 29 | 30 | @Override 31 | protected void initViewModel() { 32 | mViewModel = new WeChatViewModel(Injection.provideDataManager()); 33 | } 34 | 35 | @Override 36 | protected void bindViewModel() { 37 | mDataBinding.setViewModel(mViewModel); 38 | } 39 | 40 | @Override 41 | protected void init() { 42 | initView(); 43 | mViewModel.loadData(); 44 | } 45 | 46 | @Override 47 | protected boolean isSupportLoad() { 48 | return true; 49 | } 50 | 51 | private void initView() { 52 | mPagerAdapter = new ArticleListPagerAdapter(getChildFragmentManager()); 53 | mDataBinding.vpViewPager.setAdapter(mPagerAdapter); 54 | mDataBinding.tlTabLayout.setupWithViewPager(mDataBinding.vpViewPager); 55 | } 56 | 57 | @Override 58 | public void scrollToTop() { 59 | Fragment fragment = mPagerAdapter.getItem(mDataBinding.vpViewPager.getCurrentItem()); 60 | if (fragment instanceof ScrollToTop) { 61 | ((ScrollToTop) fragment).scrollToTop(); 62 | } 63 | } 64 | 65 | @Override 66 | public void onDestroyView() { 67 | super.onDestroyView(); 68 | mPagerAdapter.release(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/model/BannerData.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.model; 2 | 3 | import com.github.cyc.wanandroid.http.model.Banner; 4 | 5 | import java.util.List; 6 | 7 | public class BannerData { 8 | 9 | private List bannerList; 10 | 11 | public List getBannerList() { 12 | return bannerList; 13 | } 14 | 15 | public void setBannerList(List bannerList) { 16 | this.bannerList = bannerList; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/model/HomepageData.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.model; 2 | 3 | import com.github.cyc.wanandroid.http.model.ArticleList; 4 | 5 | public class HomepageData { 6 | 7 | private BannerData bannerData; 8 | private ArticleList articleList; 9 | 10 | public BannerData getBannerData() { 11 | return bannerData; 12 | } 13 | 14 | public void setBannerData(BannerData bannerData) { 15 | this.bannerData = bannerData; 16 | } 17 | 18 | public ArticleList getArticleList() { 19 | return articleList; 20 | } 21 | 22 | public void setArticleList(ArticleList articleList) { 23 | this.articleList = articleList; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewholder/ArticleViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewholder; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import com.github.cyc.wanandroid.R; 8 | import com.github.cyc.wanandroid.base.viewholder.BaseViewHolder; 9 | import com.github.cyc.wanandroid.databinding.ItemArticleBinding; 10 | import com.github.cyc.wanandroid.module.details.activity.DetailsActivity; 11 | import com.github.cyc.wanandroid.module.main.viewmodel.item.ArticleViewModel; 12 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 13 | 14 | /** 15 | * 文章的ViewHolder 16 | */ 17 | public class ArticleViewHolder extends BaseViewHolder 18 | implements DetailsNavigator { 19 | 20 | public ArticleViewHolder(@NonNull ViewGroup parent) { 21 | super(parent, R.layout.item_article); 22 | } 23 | 24 | @Override 25 | protected void initViewModel() { 26 | mViewModel = new ArticleViewModel(this); 27 | } 28 | 29 | @Override 30 | protected void bindViewModel() { 31 | mDataBinding.setViewModel(mViewModel); 32 | } 33 | 34 | @Override 35 | protected void init() { 36 | mDataBinding.tvTop.setVisibility(View.GONE); 37 | mDataBinding.tvFresh.setVisibility(View.GONE); 38 | mDataBinding.tvTag.setVisibility(View.GONE); 39 | } 40 | 41 | @Override 42 | public void startDetailsActivity(String url) { 43 | DetailsActivity.start(itemView.getContext(), url); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewholder/BannerViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewholder; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.view.ViewGroup; 5 | 6 | import com.github.cyc.wanandroid.R; 7 | import com.github.cyc.wanandroid.app.GlideImageLoader; 8 | import com.github.cyc.wanandroid.base.viewholder.BaseViewHolder; 9 | import com.github.cyc.wanandroid.databinding.ItemBannerBinding; 10 | import com.github.cyc.wanandroid.module.details.activity.DetailsActivity; 11 | import com.github.cyc.wanandroid.module.main.viewmodel.item.BannerViewModel; 12 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 13 | import com.youth.banner.BannerConfig; 14 | import com.youth.banner.Transformer; 15 | import com.youth.banner.listener.OnBannerListener; 16 | 17 | /** 18 | * Banner的ViewHolder 19 | */ 20 | public class BannerViewHolder extends BaseViewHolder 21 | implements DetailsNavigator { 22 | 23 | public BannerViewHolder(@NonNull ViewGroup parent) { 24 | super(parent, R.layout.item_banner); 25 | } 26 | 27 | @Override 28 | protected void initViewModel() { 29 | mViewModel = new BannerViewModel(this); 30 | } 31 | 32 | @Override 33 | protected void bindViewModel() { 34 | mDataBinding.setViewModel(mViewModel); 35 | } 36 | 37 | @Override 38 | protected void init() { 39 | // 设置Banner样式 40 | mDataBinding.bBanner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE); 41 | // 设置图片加载器 42 | mDataBinding.bBanner.setImageLoader(new GlideImageLoader()); 43 | // 设置Banner动画效果 44 | mDataBinding.bBanner.setBannerAnimation(Transformer.Default); 45 | // 设置指示器位置(当Banner样式中有指示器时) 46 | mDataBinding.bBanner.setIndicatorGravity(BannerConfig.RIGHT); 47 | // 设置Banner监听器 48 | mDataBinding.bBanner.setOnBannerListener(new OnBannerListener() { 49 | 50 | @Override 51 | public void OnBannerClick(int position) { 52 | mViewModel.onClickBanner(position); 53 | } 54 | }); 55 | } 56 | 57 | @Override 58 | public void startDetailsActivity(String url) { 59 | DetailsActivity.start(itemView.getContext(), url); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewholder/NavigationViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewholder; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import com.github.cyc.wanandroid.R; 8 | import com.github.cyc.wanandroid.base.viewholder.BaseViewHolder; 9 | import com.github.cyc.wanandroid.databinding.ItemNavigationBinding; 10 | import com.github.cyc.wanandroid.module.details.activity.DetailsActivity; 11 | import com.github.cyc.wanandroid.module.main.adapter.NavigationTagAdapter; 12 | import com.github.cyc.wanandroid.module.main.viewmodel.item.NavigationViewModel; 13 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 14 | import com.zhy.view.flowlayout.FlowLayout; 15 | import com.zhy.view.flowlayout.TagFlowLayout; 16 | 17 | /** 18 | * 导航的ViewHolder 19 | */ 20 | public class NavigationViewHolder extends BaseViewHolder 21 | implements DetailsNavigator { 22 | 23 | public NavigationViewHolder(@NonNull ViewGroup parent) { 24 | super(parent, R.layout.item_navigation); 25 | } 26 | 27 | @Override 28 | protected void initViewModel() { 29 | mViewModel = new NavigationViewModel(this); 30 | } 31 | 32 | @Override 33 | protected void bindViewModel() { 34 | mDataBinding.setViewModel(mViewModel); 35 | } 36 | 37 | @Override 38 | protected void init() { 39 | mDataBinding.tflFlowLayout.setAdapter(new NavigationTagAdapter()); 40 | mDataBinding.tflFlowLayout.setOnTagClickListener(new TagFlowLayout.OnTagClickListener() { 41 | 42 | @Override 43 | public boolean onTagClick(View view, int position, FlowLayout parent) { 44 | mViewModel.onClickTag(position); 45 | return true; 46 | } 47 | }); 48 | } 49 | 50 | @Override 51 | public void startDetailsActivity(String url) { 52 | DetailsActivity.start(itemView.getContext(), url); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewholder/ProjectViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewholder; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.view.ViewGroup; 5 | 6 | import com.github.cyc.wanandroid.R; 7 | import com.github.cyc.wanandroid.base.viewholder.BaseViewHolder; 8 | import com.github.cyc.wanandroid.databinding.ItemProjectBinding; 9 | import com.github.cyc.wanandroid.module.details.activity.DetailsActivity; 10 | import com.github.cyc.wanandroid.module.main.viewmodel.item.ProjectViewModel; 11 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 12 | 13 | /** 14 | * 项目的ViewHolder 15 | */ 16 | public class ProjectViewHolder extends BaseViewHolder 17 | implements DetailsNavigator { 18 | 19 | public ProjectViewHolder(@NonNull ViewGroup parent) { 20 | super(parent, R.layout.item_project); 21 | } 22 | 23 | @Override 24 | protected void initViewModel() { 25 | mViewModel = new ProjectViewModel(this); 26 | } 27 | 28 | @Override 29 | protected void bindViewModel() { 30 | mDataBinding.setViewModel(mViewModel); 31 | } 32 | 33 | @Override 34 | protected void init() { 35 | 36 | } 37 | 38 | @Override 39 | public void startDetailsActivity(String url) { 40 | DetailsActivity.start(itemView.getContext(), url); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewholder/SystemViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewholder; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.view.ViewGroup; 5 | 6 | import com.github.cyc.wanandroid.R; 7 | import com.github.cyc.wanandroid.base.viewholder.BaseViewHolder; 8 | import com.github.cyc.wanandroid.databinding.ItemSystemBinding; 9 | import com.github.cyc.wanandroid.http.model.Chapter; 10 | import com.github.cyc.wanandroid.module.main.activity.SystemDetailsActivity; 11 | import com.github.cyc.wanandroid.module.main.viewmodel.item.SystemViewModel; 12 | import com.github.cyc.wanandroid.navigator.SystemDetailsNavigator; 13 | 14 | /** 15 | * 体系的ViewHolder 16 | */ 17 | public class SystemViewHolder extends BaseViewHolder 18 | implements SystemDetailsNavigator { 19 | 20 | public SystemViewHolder(@NonNull ViewGroup parent) { 21 | super(parent, R.layout.item_system); 22 | } 23 | 24 | @Override 25 | protected void initViewModel() { 26 | mViewModel = new SystemViewModel(this); 27 | } 28 | 29 | @Override 30 | protected void bindViewModel() { 31 | mDataBinding.setViewModel(mViewModel); 32 | } 33 | 34 | @Override 35 | protected void init() { 36 | 37 | } 38 | 39 | @Override 40 | public void startSystemDetailsActivity(Chapter chapter) { 41 | SystemDetailsActivity.start(itemView.getContext(), chapter); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/MainViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel; 2 | 3 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 4 | 5 | /** 6 | * 主页的ViewModel 7 | */ 8 | public class MainViewModel extends BaseViewModel { 9 | 10 | public MainViewModel() { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/NavigationViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel; 2 | 3 | import android.databinding.ObservableArrayList; 4 | import android.databinding.ObservableList; 5 | import android.support.annotation.NonNull; 6 | 7 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 8 | import com.github.cyc.wanandroid.data.DataManager; 9 | import com.github.cyc.wanandroid.enums.LoadState; 10 | import com.github.cyc.wanandroid.http.base.BaseObserver; 11 | import com.github.cyc.wanandroid.http.model.Navigation; 12 | import com.github.cyc.wanandroid.utils.RxUtils; 13 | import com.github.cyc.wanandroid.utils.Utils; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * 导航tab的ViewModel 19 | */ 20 | public class NavigationViewModel extends BaseViewModel { 21 | 22 | public final ObservableList dataList = new ObservableArrayList<>(); 23 | 24 | public final ObservableList titleList = new ObservableArrayList<>(); 25 | 26 | private DataManager mDataManager; 27 | 28 | public NavigationViewModel(@NonNull DataManager dataManager) { 29 | mDataManager = dataManager; 30 | } 31 | 32 | public void loadData() { 33 | loadState.set(LoadState.LOADING); 34 | addDisposable(mDataManager.getNavigationListData() 35 | .compose(RxUtils.applySchedulers()) 36 | .subscribeWith(new BaseObserver>(loadState) { 37 | 38 | @Override 39 | public void onNextX(List navigationList) { 40 | if (!Utils.isListEmpty(navigationList)) { 41 | for (Navigation navigation : navigationList) { 42 | titleList.add(navigation.getName()); 43 | } 44 | dataList.addAll(navigationList); 45 | 46 | loadState.set(LoadState.SUCCESS); 47 | } else { 48 | loadState.set(LoadState.NO_DATA); 49 | } 50 | } 51 | })); 52 | } 53 | 54 | @Override 55 | public void reloadData() { 56 | loadData(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/ProjectViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel; 2 | 3 | import android.databinding.ObservableArrayList; 4 | import android.databinding.ObservableList; 5 | import android.support.annotation.NonNull; 6 | 7 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 8 | import com.github.cyc.wanandroid.data.DataManager; 9 | import com.github.cyc.wanandroid.enums.LoadState; 10 | import com.github.cyc.wanandroid.http.base.BaseObserver; 11 | import com.github.cyc.wanandroid.http.model.Chapter; 12 | import com.github.cyc.wanandroid.utils.RxUtils; 13 | import com.github.cyc.wanandroid.utils.Utils; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * 项目tab的ViewModel 19 | */ 20 | public class ProjectViewModel extends BaseViewModel { 21 | 22 | public final ObservableList dataList = new ObservableArrayList<>(); 23 | 24 | private DataManager mDataManager; 25 | 26 | public ProjectViewModel(@NonNull DataManager dataManager) { 27 | mDataManager = dataManager; 28 | } 29 | 30 | public void loadData() { 31 | loadState.set(LoadState.LOADING); 32 | addDisposable(mDataManager.getProjectListData() 33 | .compose(RxUtils.applySchedulers()) 34 | .subscribeWith(new BaseObserver>(loadState) { 35 | 36 | @Override 37 | public void onNextX(List chapterList) { 38 | if (!Utils.isListEmpty(chapterList)) { 39 | dataList.addAll(chapterList); 40 | loadState.set(LoadState.SUCCESS); 41 | } else { 42 | loadState.set(LoadState.NO_DATA); 43 | } 44 | } 45 | })); 46 | } 47 | 48 | @Override 49 | public void reloadData() { 50 | loadData(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/SystemViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel; 2 | 3 | import android.databinding.ObservableArrayList; 4 | import android.databinding.ObservableList; 5 | import android.support.annotation.NonNull; 6 | 7 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 8 | import com.github.cyc.wanandroid.data.DataManager; 9 | import com.github.cyc.wanandroid.enums.LoadState; 10 | import com.github.cyc.wanandroid.enums.RefreshState; 11 | import com.github.cyc.wanandroid.http.base.BaseObserver; 12 | import com.github.cyc.wanandroid.http.model.Chapter; 13 | import com.github.cyc.wanandroid.utils.RxUtils; 14 | import com.github.cyc.wanandroid.utils.Utils; 15 | 16 | import java.util.List; 17 | 18 | /** 19 | * 体系tab的ViewModel 20 | */ 21 | public class SystemViewModel extends BaseViewModel { 22 | 23 | public final ObservableList dataList = new ObservableArrayList<>(); 24 | 25 | private DataManager mDataManager; 26 | 27 | private boolean mRefresh; 28 | 29 | public SystemViewModel(@NonNull DataManager dataManager) { 30 | mDataManager = dataManager; 31 | } 32 | 33 | public void loadData() { 34 | mRefresh = false; 35 | getAllData(); 36 | } 37 | 38 | @Override 39 | public void reloadData() { 40 | loadData(); 41 | } 42 | 43 | public void refreshData() { 44 | mRefresh = true; 45 | getAllData(); 46 | } 47 | 48 | private void getAllData() { 49 | if (!mRefresh) { 50 | loadState.set(LoadState.LOADING); 51 | } 52 | 53 | addDisposable(mDataManager.getSystemListData() 54 | .compose(RxUtils.applySchedulers()) 55 | .subscribeWith(new BaseObserver>(loadState, !mRefresh) { 56 | 57 | @Override 58 | public void onNextX(List chapterList) { 59 | if (mRefresh) { 60 | setRefreshState(RefreshState.REFRESH_END); 61 | } 62 | 63 | if (!Utils.isListEmpty(chapterList)) { 64 | dataList.clear(); 65 | dataList.addAll(chapterList); 66 | 67 | if (!mRefresh) { 68 | loadState.set(LoadState.SUCCESS); 69 | } 70 | } else { 71 | if (!mRefresh) { 72 | loadState.set(LoadState.NO_DATA); 73 | } 74 | } 75 | } 76 | 77 | @Override 78 | public void onErrorX(int errorCode, String errorMsg) { 79 | if (mRefresh) { 80 | setRefreshState(RefreshState.REFRESH_END); 81 | } 82 | } 83 | })); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/WeChatViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel; 2 | 3 | import android.databinding.ObservableArrayList; 4 | import android.databinding.ObservableList; 5 | import android.support.annotation.NonNull; 6 | 7 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 8 | import com.github.cyc.wanandroid.data.DataManager; 9 | import com.github.cyc.wanandroid.enums.LoadState; 10 | import com.github.cyc.wanandroid.http.base.BaseObserver; 11 | import com.github.cyc.wanandroid.http.model.Chapter; 12 | import com.github.cyc.wanandroid.utils.RxUtils; 13 | import com.github.cyc.wanandroid.utils.Utils; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * 公众号tab的ViewModel 19 | */ 20 | public class WeChatViewModel extends BaseViewModel { 21 | 22 | public final ObservableList dataList = new ObservableArrayList<>(); 23 | 24 | private DataManager mDataManager; 25 | 26 | public WeChatViewModel(@NonNull DataManager dataManager) { 27 | mDataManager = dataManager; 28 | } 29 | 30 | public void loadData() { 31 | loadState.set(LoadState.LOADING); 32 | addDisposable(mDataManager.getWeChatListData() 33 | .compose(RxUtils.applySchedulers()) 34 | .subscribeWith(new BaseObserver>(loadState) { 35 | 36 | @Override 37 | public void onNextX(List chapterList) { 38 | if (!Utils.isListEmpty(chapterList)) { 39 | dataList.addAll(chapterList); 40 | loadState.set(LoadState.SUCCESS); 41 | } else { 42 | loadState.set(LoadState.NO_DATA); 43 | } 44 | } 45 | })); 46 | } 47 | 48 | @Override 49 | public void reloadData() { 50 | loadData(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/item/ArticleViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel.item; 2 | 3 | import android.databinding.ObservableBoolean; 4 | import android.databinding.ObservableField; 5 | import android.support.annotation.NonNull; 6 | import android.text.TextUtils; 7 | 8 | import com.github.cyc.wanandroid.R; 9 | import com.github.cyc.wanandroid.base.viewmodel.BaseItemViewModel; 10 | import com.github.cyc.wanandroid.http.model.Article; 11 | import com.github.cyc.wanandroid.http.model.Tag; 12 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 13 | import com.github.cyc.wanandroid.utils.ResourceUtils; 14 | import com.github.cyc.wanandroid.utils.Utils; 15 | 16 | import java.util.List; 17 | 18 | /** 19 | * 文章的ViewModel 20 | */ 21 | public class ArticleViewModel extends BaseItemViewModel
{ 22 | 23 | public final ObservableField tag = new ObservableField<>(); 24 | 25 | public final ObservableField author = new ObservableField<>(); 26 | 27 | public final ObservableField time = new ObservableField<>(); 28 | 29 | public final ObservableField title = new ObservableField<>(); 30 | 31 | public final ObservableField chapterName = new ObservableField<>(); 32 | 33 | public final ObservableBoolean top = new ObservableBoolean(false); 34 | 35 | public final ObservableBoolean fresh = new ObservableBoolean(false); 36 | 37 | private DetailsNavigator mDetailsNavigator; 38 | 39 | public ArticleViewModel(@NonNull DetailsNavigator detailsNavigator) { 40 | mDetailsNavigator = detailsNavigator; 41 | } 42 | 43 | @Override 44 | protected void setAllModel(@NonNull Article article) { 45 | author.set(article.getAuthor()); 46 | time.set(article.getNiceDate()); 47 | title.set(article.getTitle()); 48 | chapterName.set(String.format(ResourceUtils.getString(R.string.chapter_name_format), article.getSuperChapterName(), article.getChapterName())); 49 | 50 | List tagList = article.getTags(); 51 | if (!Utils.isListEmpty(tagList)) { 52 | tag.set(tagList.get(0).getName()); 53 | } else { 54 | tag.set(""); 55 | } 56 | 57 | Boolean top = article.isTop(); 58 | if (top != null) { 59 | this.top.set(top); 60 | } else { 61 | this.top.set(false); 62 | } 63 | 64 | Boolean fresh = article.isFresh(); 65 | if (fresh != null) { 66 | this.fresh.set(fresh); 67 | } else { 68 | this.fresh.set(false); 69 | } 70 | } 71 | 72 | public void onClickItem() { 73 | Article article = getBaseModel(); 74 | if (article != null && !TextUtils.isEmpty(article.getLink())) { 75 | mDetailsNavigator.startDetailsActivity(article.getLink()); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/item/BannerViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel.item; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.github.cyc.wanandroid.base.viewmodel.BaseItemViewModel; 6 | import com.github.cyc.wanandroid.http.model.Banner; 7 | import com.github.cyc.wanandroid.module.main.model.BannerData; 8 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 9 | 10 | /** 11 | * Banner的ViewModel 12 | */ 13 | public class BannerViewModel extends BaseItemViewModel { 14 | 15 | private DetailsNavigator mDetailsNavigator; 16 | 17 | public BannerViewModel(@NonNull DetailsNavigator detailsNavigator) { 18 | mDetailsNavigator = detailsNavigator; 19 | } 20 | 21 | @Override 22 | protected void setAllModel(@NonNull BannerData bannerData) { 23 | 24 | } 25 | 26 | public void onClickBanner(int position) { 27 | BannerData bannerData = getBaseModel(); 28 | if (bannerData != null && bannerData.getBannerList() != null 29 | && bannerData.getBannerList().size() > position) { 30 | Banner banner = bannerData.getBannerList().get(position); 31 | mDetailsNavigator.startDetailsActivity(banner.getUrl()); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/item/NavigationViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel.item; 2 | 3 | import android.databinding.ObservableArrayList; 4 | import android.databinding.ObservableField; 5 | import android.databinding.ObservableList; 6 | import android.support.annotation.NonNull; 7 | 8 | import com.github.cyc.wanandroid.base.viewmodel.BaseItemViewModel; 9 | import com.github.cyc.wanandroid.http.model.Article; 10 | import com.github.cyc.wanandroid.http.model.Navigation; 11 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 12 | 13 | /** 14 | * 导航的ViewModel 15 | */ 16 | public class NavigationViewModel extends BaseItemViewModel { 17 | 18 | public final ObservableField name = new ObservableField<>(); 19 | 20 | public final ObservableList
dataList = new ObservableArrayList<>(); 21 | 22 | private DetailsNavigator mDetailsNavigator; 23 | 24 | public NavigationViewModel(@NonNull DetailsNavigator detailsNavigator) { 25 | mDetailsNavigator = detailsNavigator; 26 | } 27 | 28 | @Override 29 | protected void setAllModel(@NonNull Navigation navigation) { 30 | name.set(navigation.getName()); 31 | dataList.addAll(navigation.getArticles()); 32 | } 33 | 34 | public void onClickTag(int position) { 35 | if (dataList.size() > position) { 36 | Article article = dataList.get(position); 37 | mDetailsNavigator.startDetailsActivity(article.getLink()); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/item/ProjectViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel.item; 2 | 3 | import android.databinding.ObservableField; 4 | import android.support.annotation.NonNull; 5 | import android.text.TextUtils; 6 | 7 | import com.github.cyc.wanandroid.base.viewmodel.BaseItemViewModel; 8 | import com.github.cyc.wanandroid.http.model.Article; 9 | import com.github.cyc.wanandroid.navigator.DetailsNavigator; 10 | 11 | /** 12 | * 项目的ViewModel 13 | */ 14 | public class ProjectViewModel extends BaseItemViewModel
{ 15 | 16 | public final ObservableField imageUrl = new ObservableField<>(); 17 | 18 | public final ObservableField title = new ObservableField<>(); 19 | 20 | public final ObservableField desc = new ObservableField<>(); 21 | 22 | public final ObservableField time = new ObservableField<>(); 23 | 24 | public final ObservableField author = new ObservableField<>(); 25 | 26 | private DetailsNavigator mDetailsNavigator; 27 | 28 | public ProjectViewModel(@NonNull DetailsNavigator detailsNavigator) { 29 | mDetailsNavigator = detailsNavigator; 30 | } 31 | 32 | @Override 33 | protected void setAllModel(@NonNull Article article) { 34 | imageUrl.set(article.getEnvelopePic()); 35 | title.set(article.getTitle()); 36 | desc.set(article.getDesc()); 37 | time.set(article.getNiceDate()); 38 | author.set(article.getAuthor()); 39 | } 40 | 41 | public void onClickItem() { 42 | Article article = getBaseModel(); 43 | if (article != null && !TextUtils.isEmpty(article.getLink())) { 44 | mDetailsNavigator.startDetailsActivity(article.getLink()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/main/viewmodel/item/SystemViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.main.viewmodel.item; 2 | 3 | import android.databinding.ObservableField; 4 | import android.support.annotation.NonNull; 5 | 6 | import com.github.cyc.wanandroid.base.viewmodel.BaseItemViewModel; 7 | import com.github.cyc.wanandroid.http.model.Chapter; 8 | import com.github.cyc.wanandroid.navigator.SystemDetailsNavigator; 9 | import com.github.cyc.wanandroid.utils.Utils; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * 体系的ViewModel 15 | */ 16 | public class SystemViewModel extends BaseItemViewModel { 17 | 18 | public ObservableField parent = new ObservableField<>(); 19 | 20 | public ObservableField children = new ObservableField<>(); 21 | 22 | private SystemDetailsNavigator mSystemDetailsNavigator; 23 | 24 | public SystemViewModel(@NonNull SystemDetailsNavigator systemDetailsNavigator) { 25 | mSystemDetailsNavigator = systemDetailsNavigator; 26 | } 27 | 28 | @Override 29 | protected void setAllModel(@NonNull Chapter chapter) { 30 | parent.set(chapter.getName()); 31 | 32 | List childList = chapter.getChildren(); 33 | if (!Utils.isListEmpty(childList)) { 34 | StringBuilder builder = new StringBuilder(); 35 | for (int i = 0; i < childList.size(); i++) { 36 | if (i > 0) { 37 | builder.append(" "); 38 | } 39 | builder.append(childList.get(i).getName()); 40 | } 41 | 42 | children.set(builder.toString()); 43 | } else { 44 | children.set(""); 45 | } 46 | } 47 | 48 | public void onClickItem() { 49 | Chapter chapter = getBaseModel(); 50 | if (chapter != null) { 51 | mSystemDetailsNavigator.startSystemDetailsActivity(chapter); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/splash/activity/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.splash.activity; 2 | 3 | import com.github.cyc.wanandroid.R; 4 | import com.github.cyc.wanandroid.base.activity.BaseActivity; 5 | import com.github.cyc.wanandroid.databinding.ActivitySplashBinding; 6 | import com.github.cyc.wanandroid.module.main.activity.MainActivity; 7 | import com.github.cyc.wanandroid.module.splash.viewmodel.SplashViewModel; 8 | import com.github.cyc.wanandroid.navigator.MainNavigator; 9 | 10 | /** 11 | * 闪屏页 12 | */ 13 | public class SplashActivity extends BaseActivity 14 | implements MainNavigator { 15 | 16 | @Override 17 | protected int getLayoutResId() { 18 | return R.layout.activity_splash; 19 | } 20 | 21 | @Override 22 | protected void initViewModel() { 23 | mViewModel = new SplashViewModel(this); 24 | } 25 | 26 | @Override 27 | protected void bindViewModel() { 28 | 29 | } 30 | 31 | @Override 32 | protected void init() { 33 | mViewModel.startTimer(); 34 | } 35 | 36 | @Override 37 | public void startMainActivity() { 38 | MainActivity.start(this); 39 | finish(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/module/splash/viewmodel/SplashViewModel.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.module.splash.viewmodel; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.github.cyc.wanandroid.app.Constant; 6 | import com.github.cyc.wanandroid.base.viewmodel.BaseViewModel; 7 | import com.github.cyc.wanandroid.navigator.MainNavigator; 8 | 9 | import java.util.concurrent.TimeUnit; 10 | 11 | import io.reactivex.Observable; 12 | import io.reactivex.functions.Consumer; 13 | 14 | /** 15 | * 闪屏页的ViewModel 16 | */ 17 | public class SplashViewModel extends BaseViewModel { 18 | 19 | private MainNavigator mMainNavigator; 20 | 21 | public SplashViewModel(@NonNull MainNavigator mainNavigator) { 22 | mMainNavigator = mainNavigator; 23 | } 24 | 25 | public void startTimer() { 26 | addDisposable(Observable.timer(Constant.SPLASH_TIME, TimeUnit.MILLISECONDS) 27 | .subscribe(new Consumer() { 28 | 29 | @Override 30 | public void accept(Long aLong) throws Exception { 31 | mMainNavigator.startMainActivity(); 32 | } 33 | })); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/navigator/DetailsNavigator.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.navigator; 2 | 3 | /** 4 | * 详情页导航接口 5 | */ 6 | public interface DetailsNavigator { 7 | 8 | /** 9 | * 打开详情页 10 | * 11 | * @param url URL 12 | */ 13 | void startDetailsActivity(String url); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/navigator/MainNavigator.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.navigator; 2 | 3 | /** 4 | * 主页导航接口 5 | */ 6 | public interface MainNavigator { 7 | 8 | /** 9 | * 打开主页 10 | */ 11 | void startMainActivity(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/navigator/SystemDetailsNavigator.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.navigator; 2 | 3 | import com.github.cyc.wanandroid.http.model.Chapter; 4 | 5 | /** 6 | * 体系详情页导航接口 7 | */ 8 | public interface SystemDetailsNavigator { 9 | 10 | /** 11 | * 打开体系详情页 12 | * 13 | * @param chapter Chapter数据 14 | */ 15 | void startSystemDetailsActivity(Chapter chapter); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/utils/ResourceUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.utils; 2 | 3 | import android.support.annotation.ColorRes; 4 | import android.support.annotation.StringRes; 5 | import android.support.v4.content.ContextCompat; 6 | 7 | import com.github.cyc.wanandroid.app.WanApplication; 8 | 9 | /** 10 | * 资源工具类 11 | */ 12 | public final class ResourceUtils { 13 | 14 | private ResourceUtils() { 15 | 16 | } 17 | 18 | /** 19 | * 获取字符串资源 20 | * 21 | * @param resId 字符串资源ID 22 | * @return 字符串 23 | */ 24 | public static String getString(@StringRes int resId) { 25 | return WanApplication.getInstance().getString(resId); 26 | } 27 | 28 | /** 29 | * 获取颜色资源 30 | * 31 | * @param resId 颜色资源ID 32 | * @return 颜色 33 | */ 34 | public static int getColor(@ColorRes int resId) { 35 | return ContextCompat.getColor(WanApplication.getInstance(), resId); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/utils/RxUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.utils; 2 | 3 | import io.reactivex.Observable; 4 | import io.reactivex.ObservableSource; 5 | import io.reactivex.ObservableTransformer; 6 | import io.reactivex.android.schedulers.AndroidSchedulers; 7 | import io.reactivex.schedulers.Schedulers; 8 | 9 | /** 10 | * RX工具类 11 | */ 12 | public final class RxUtils { 13 | 14 | private RxUtils() { 15 | 16 | } 17 | 18 | /** 19 | * IO操作的线程切换 20 | * 21 | * @param 指定的泛型类型 22 | * @return ObservableTransformer 23 | */ 24 | public static ObservableTransformer applySchedulers() { 25 | return new ObservableTransformer() { 26 | 27 | @Override 28 | public ObservableSource apply(Observable upstream) { 29 | return upstream.subscribeOn(Schedulers.io()) 30 | .observeOn(AndroidSchedulers.mainThread()); 31 | } 32 | }; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/utils/ToastUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.utils; 2 | 3 | import android.support.annotation.StringRes; 4 | import android.widget.Toast; 5 | 6 | import com.github.cyc.wanandroid.app.WanApplication; 7 | 8 | /** 9 | * Toast工具类 10 | */ 11 | public final class ToastUtils { 12 | 13 | private ToastUtils() { 14 | 15 | } 16 | 17 | /** 18 | * 显示一条Toast 19 | * 20 | * @param msg 消息 21 | */ 22 | public static void show(String msg) { 23 | Toast.makeText(WanApplication.getInstance(), msg, Toast.LENGTH_SHORT).show(); 24 | } 25 | 26 | /** 27 | * 显示一条Toast 28 | * 29 | * @param resId 消息资源ID 30 | */ 31 | public static void show(@StringRes int resId) { 32 | Toast.makeText(WanApplication.getInstance(), resId, Toast.LENGTH_SHORT).show(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/cyc/wanandroid/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid.utils; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 工具类 7 | */ 8 | public final class Utils { 9 | 10 | private Utils() { 11 | 12 | } 13 | 14 | /** 15 | * 判断列表是否为空 16 | * 17 | * @param list 列表 18 | * @return true表示为空,false表示不为空 19 | */ 20 | public static boolean isListEmpty(List list) { 21 | return list == null || list.size() == 0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/res/color/selector_bottom_nav_item_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/animated_rotate_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_back.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_upward.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_homepage.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_project.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 14 | 17 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_system.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_timelapse.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_we_chat.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 14 | 17 | 20 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_navigation_tag.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_label_green.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_label_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_base.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_details.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 18 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 19 | 20 | 24 | 25 | 28 | 29 | 34 | 35 | 46 | 47 | 57 | 58 | 59 | 69 | 70 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 22 | 23 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_system_details.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 15 | 16 | 22 | 23 | 29 | 30 | 31 | 36 | 37 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_article_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 23 | 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_base.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_homepage.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 23 | 24 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 19 | 20 | 31 | 32 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_project.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 19 | 20 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_project_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 23 | 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_system.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 22 | 23 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_we_chat.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 19 | 20 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 17 | 18 | 31 | 32 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_system.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 26 | 27 | 31 | 32 | 42 | 43 | 55 | 56 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_load_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 20 | 21 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_nav_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_navigation_tag.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_no_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 20 | 21 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_no_network.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 17 | 18 | 28 | 29 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_bottom_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 18 | 19 | 23 | 24 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_drawer_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @color/primary 5 | @color/primary_light 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2196F3 4 | #1976D2 5 | #BBDEFB 6 | #4CAF50 7 | #212121 8 | #757575 9 | #FFFFFF 10 | #BDBDBD 11 | 12 | #F44336 13 | #4CAF50 14 | #2196f3 15 | #9E9E9E 16 | #616161 17 | #F5F5F5 18 | 19 | #FFFFFF 20 | 21 | #FFFFFF 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | WanAndroid 3 | 4 | 5 | 加载中… 6 | 加载出错 7 | 没有网络,点击重试 8 | 没有数据 9 | 10 | 11 | 未知错误 12 | HTTP错误 13 | 当前网络不可用,请检查您的网络连接 14 | 解析错误 15 | SSL错误 16 | 17 | 18 | 首页 19 | 项目 20 | 体系 21 | 导航 22 | 公众号 23 | 24 | 25 | 设置 26 | 关于 27 | 28 | 置顶 29 | 30 | %1$s / %2$s 31 | 再按一次退出程序 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings_behavior.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.github.cyc.wanandroid.behavior.BottomNavigationBehavior 4 | com.github.cyc.wanandroid.behavior.FloatingActionButtonBehavior 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 16 | 17 | 26 | 27 | 32 | 33 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/cyc/wanandroid/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.github.cyc.wanandroid; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:4.2.2' 11 | 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 | google() 20 | jcenter() 21 | } 22 | } 23 | 24 | task clean(type: Delete) { 25 | delete rootProject.buildDir 26 | } 27 | 28 | // Define versions in a single place 29 | ext { 30 | // Sdk 31 | minSdkVersion = 15 32 | targetSdkVersion = 28 33 | compileSdkVersion = 28 34 | 35 | // Support library 36 | supportLibraryVersion = '28.0.0' 37 | constraintLayoutVersion = '1.1.3' 38 | 39 | // Test 40 | junitVersion = '4.12' 41 | 42 | // Android test 43 | runnerVersion = '1.0.2' 44 | espressoVersion = '3.0.2' 45 | 46 | // App 47 | leakCanaryVersion = '1.6.3' 48 | loggerVersion = '2.2.0' 49 | lifecycleVersion = '1.1.1' 50 | okHttpVersion = '3.13.1' 51 | retrofitVersion = '2.5.0' 52 | rxJavaVersion = '2.2.7' 53 | rxAndroidVersion = '2.1.1' 54 | glideVersion = '4.9.0' 55 | materialRefreshLayoutVersion = '1.3.0' 56 | bannerVersion = '1.4.10' 57 | agentWebVersion = '4.0.2' 58 | verticalTabLayoutVersion = '1.2.9' 59 | flowLayoutVersion = '1.1.2' 60 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m --add-opens java.base/java.io=ALL-UNNAMED 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /node_modules/conventional-commit-types/.npmignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # node-waf configuration 29 | .lock-wscript 30 | 31 | # Compiled binary addons (http://nodejs.org/api/addons.html) 32 | build/Release 33 | 34 | # Dependency directories 35 | node_modules 36 | jspm_packages 37 | 38 | # Optional npm cache directory 39 | .npm 40 | 41 | # Optional REPL history 42 | .node_repl_history 43 | -------------------------------------------------------------------------------- /node_modules/conventional-commit-types/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | -------------------------------------------------------------------------------- /node_modules/conventional-commit-types/README.md: -------------------------------------------------------------------------------- 1 | # conventional-commit-types 2 | 3 | [![npm](https://img.shields.io/npm/v/conventional-commit-types.svg?maxAge=2592000)](https://www.npmjs.com/package/conventional-commit-types) 4 | [![Build Status](https://img.shields.io/travis/commitizen/conventional-commit-types.svg?maxAge=2592000)](https://travis-ci.org/commitizen/conventional-commit-types) 5 | 6 | List of conventional commit types. 7 | 8 | ## Spec 9 | 10 | Exports an object with a `types` key whose value is an object whose keys are type names and whose values are objects with key-value pairs such as `description` as string, optional `title` as string, etc. See [index.json](index.json). Any alternatives should follow the same spec. 11 | 12 | ## Etc. 13 | 14 | Used by [commitizen/cz-conventional-changelog](https://github.com/commitizen/cz-conventional-changelog) for [commitizen/cz-cli](https://github.com/commitizen/cz-cli). 15 | 16 | Can be used with [kentcdodds/validate-commit-msg](https://github.com/kentcdodds/validate-commit-msg#types). 17 | 18 | Commit types originally from: 19 | * [AngularJS Git Commit Message Conventions](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type) 20 | * [commitizen/cz-conventional-changelog](https://github.com/commitizen/cz-conventional-changelog) 21 | 22 | Created for [AndersDJohnson/conventional-commit-types-cli](https://github.com/AndersDJohnson/conventional-commit-types-cli). 23 | -------------------------------------------------------------------------------- /node_modules/conventional-commit-types/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "types": { 3 | "feat": { 4 | "description": "A new feature", 5 | "title": "Features" 6 | }, 7 | "fix": { 8 | "description": "A bug fix", 9 | "title": "Bug Fixes" 10 | }, 11 | "docs": { 12 | "description": "Documentation only changes", 13 | "title": "Documentation" 14 | }, 15 | "style": { 16 | "description": "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)", 17 | "title": "Styles" 18 | }, 19 | "refactor": { 20 | "description": "A code change that neither fixes a bug nor adds a feature", 21 | "title": "Code Refactoring" 22 | }, 23 | "perf": { 24 | "description": "A code change that improves performance", 25 | "title": "Performance Improvements" 26 | }, 27 | "test": { 28 | "description": "Adding missing tests or correcting existing tests", 29 | "title": "Tests" 30 | }, 31 | "build": { 32 | "description": "Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)", 33 | "title": "Builds" 34 | }, 35 | "ci": { 36 | "description": "Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)", 37 | "title": "Continuous Integrations" 38 | }, 39 | "chore": { 40 | "description": "Other changes that don't modify src or test files", 41 | "title": "Chores" 42 | }, 43 | "revert": { 44 | "description": "Reverts a previous commit", 45 | "title": "Reverts" 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /node_modules/conventional-commit-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "conventional-commit-types@^2.0.0", 3 | "_id": "conventional-commit-types@2.2.0", 4 | "_inBundle": false, 5 | "_integrity": "sha1-XblXOdbCEqy+e29lahG5QLqmiUY=", 6 | "_location": "/conventional-commit-types", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "range", 10 | "registry": true, 11 | "raw": "conventional-commit-types@^2.0.0", 12 | "name": "conventional-commit-types", 13 | "escapedName": "conventional-commit-types", 14 | "rawSpec": "^2.0.0", 15 | "saveSpec": null, 16 | "fetchSpec": "^2.0.0" 17 | }, 18 | "_requiredBy": [ 19 | "/cz-conventional-changelog" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-2.2.0.tgz", 22 | "_shasum": "5db95739d6c212acbe7b6f656a11b940baa68946", 23 | "_spec": "conventional-commit-types@^2.0.0", 24 | "_where": "/Users/luyanli/Android/WanAndroid-Java/node_modules/cz-conventional-changelog", 25 | "author": { 26 | "name": "Anders D. Johnson", 27 | "url": "https://andrz.me/" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/commitizen/conventional-commit-types/issues" 31 | }, 32 | "bundleDependencies": false, 33 | "deprecated": false, 34 | "description": "List of conventional commit types.", 35 | "devDependencies": { 36 | "json": "^9.0.4" 37 | }, 38 | "homepage": "https://github.com/commitizen/conventional-commit-types#readme", 39 | "keywords": [], 40 | "license": "ISC", 41 | "main": "index.json", 42 | "name": "conventional-commit-types", 43 | "repository": { 44 | "type": "git", 45 | "url": "git+https://github.com/commitizen/conventional-commit-types.git" 46 | }, 47 | "scripts": { 48 | "test": "json -f index.json" 49 | }, 50 | "version": "2.2.0" 51 | } 52 | -------------------------------------------------------------------------------- /node_modules/cz-conventional-changelog/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules -------------------------------------------------------------------------------- /node_modules/cz-conventional-changelog/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - node_modules 6 | notifications: 7 | email: false 8 | node_js: 9 | - '4' 10 | before_install: 11 | - npm i -g npm@^2.0.0 12 | before_script: 13 | - npm prune 14 | after_success: 15 | - npm run semantic-release 16 | branches: 17 | only: 18 | - master 19 | -------------------------------------------------------------------------------- /node_modules/cz-conventional-changelog/README.md: -------------------------------------------------------------------------------- 1 | # cz-conventional-changelog 2 | 3 | Status: 4 | [![npm version](https://img.shields.io/npm/v/cz-conventional-changelog.svg?style=flat-square)](https://www.npmjs.org/package/cz-conventional-changelog) 5 | [![npm downloads](https://img.shields.io/npm/dm/cz-conventional-changelog.svg?style=flat-square)](http://npm-stat.com/charts.html?package=cz-conventional-changelog&from=2015-08-01) 6 | [![Build Status](https://img.shields.io/travis/commitizen/cz-conventional-changelog.svg?style=flat-square)](https://travis-ci.org/commitizen/cz-conventional-changelog) 7 | 8 | Part of the [commitizen](https://github.com/commitizen/cz-cli) family. Prompts for [conventional changelog](https://github.com/stevemao/conventional-changelog-angular/blob/master/index.js) standard. 9 | -------------------------------------------------------------------------------- /node_modules/cz-conventional-changelog/index.js: -------------------------------------------------------------------------------- 1 | "format cjs"; 2 | 3 | var engine = require('./engine'); 4 | var conventionalCommitTypes = require('conventional-commit-types'); 5 | 6 | module.exports = engine({ 7 | types: conventionalCommitTypes.types 8 | }); 9 | -------------------------------------------------------------------------------- /node_modules/cz-conventional-changelog/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "cz-conventional-changelog", 3 | "_id": "cz-conventional-changelog@2.1.0", 4 | "_inBundle": false, 5 | "_integrity": "sha1-L0vHOQ4yROTfKT5ro1Hkx0Cnx2Q=", 6 | "_location": "/cz-conventional-changelog", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "cz-conventional-changelog", 12 | "name": "cz-conventional-changelog", 13 | "escapedName": "cz-conventional-changelog", 14 | "rawSpec": "", 15 | "saveSpec": null, 16 | "fetchSpec": "latest" 17 | }, 18 | "_requiredBy": [ 19 | "#DEV:/", 20 | "#USER" 21 | ], 22 | "_resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz", 23 | "_shasum": "2f4bc7390e3244e4df293e6ba351e4c740a7c764", 24 | "_spec": "cz-conventional-changelog", 25 | "_where": "/Users/luyanli/Android/WanAndroid-Java", 26 | "author": { 27 | "name": "Jim Cummins", 28 | "email": "jimthedev@gmail.com" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/commitizen/cz-conventional-changelog/issues" 32 | }, 33 | "bundleDependencies": false, 34 | "config": { 35 | "commitizen": { 36 | "path": "./index.js" 37 | } 38 | }, 39 | "dependencies": { 40 | "conventional-commit-types": "^2.0.0", 41 | "lodash.map": "^4.5.1", 42 | "longest": "^1.0.1", 43 | "right-pad": "^1.0.1", 44 | "word-wrap": "^1.0.3" 45 | }, 46 | "deprecated": false, 47 | "description": "Commitizen adapter following the conventional-changelog format.", 48 | "devDependencies": { 49 | "commitizen": "2.9.6", 50 | "semantic-release": "^6.3.2" 51 | }, 52 | "homepage": "https://github.com/commitizen/cz-conventional-changelog", 53 | "license": "MIT", 54 | "main": "index.js", 55 | "name": "cz-conventional-changelog", 56 | "repository": { 57 | "type": "git", 58 | "url": "git+https://github.com/commitizen/cz-conventional-changelog.git" 59 | }, 60 | "scripts": { 61 | "commit": "git-cz", 62 | "semantic-release": "semantic-release pre && npm publish && semantic-release post", 63 | "test": "echo 'Tests need to be setup!'" 64 | }, 65 | "version": "2.1.0" 66 | } 67 | -------------------------------------------------------------------------------- /node_modules/lodash.map/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright jQuery Foundation and other contributors 2 | 3 | Based on Underscore.js, copyright Jeremy Ashkenas, 4 | DocumentCloud and Investigative Reporters & Editors 5 | 6 | This software consists of voluntary contributions made by many 7 | individuals. For exact contribution history, see the revision history 8 | available at https://github.com/lodash/lodash 9 | 10 | The following license applies to all parts of this software except as 11 | documented below: 12 | 13 | ==== 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining 16 | a copy of this software and associated documentation files (the 17 | "Software"), to deal in the Software without restriction, including 18 | without limitation the rights to use, copy, modify, merge, publish, 19 | distribute, sublicense, and/or sell copies of the Software, and to 20 | permit persons to whom the Software is furnished to do so, subject to 21 | the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be 24 | included in all copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 30 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 31 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 32 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 | 34 | ==== 35 | 36 | Copyright and related rights for sample code are waived via CC0. Sample 37 | code is defined as all source code displayed within the prose of the 38 | documentation. 39 | 40 | CC0: http://creativecommons.org/publicdomain/zero/1.0/ 41 | 42 | ==== 43 | 44 | Files located in the node_modules and vendor directories are externally 45 | maintained libraries used by this software which have their own 46 | licenses; we recommend you read them, as their terms may differ from the 47 | terms above. 48 | -------------------------------------------------------------------------------- /node_modules/lodash.map/README.md: -------------------------------------------------------------------------------- 1 | # lodash.map v4.6.0 2 | 3 | The [lodash](https://lodash.com/) method `_.map` exported as a [Node.js](https://nodejs.org/) module. 4 | 5 | ## Installation 6 | 7 | Using npm: 8 | ```bash 9 | $ {sudo -H} npm i -g npm 10 | $ npm i --save lodash.map 11 | ``` 12 | 13 | In Node.js: 14 | ```js 15 | var map = require('lodash.map'); 16 | ``` 17 | 18 | See the [documentation](https://lodash.com/docs#map) or [package source](https://github.com/lodash/lodash/blob/4.6.0-npm-packages/lodash.map) for more details. 19 | -------------------------------------------------------------------------------- /node_modules/lodash.map/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "lodash.map@^4.5.1", 3 | "_id": "lodash.map@4.6.0", 4 | "_inBundle": false, 5 | "_integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", 6 | "_location": "/lodash.map", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "range", 10 | "registry": true, 11 | "raw": "lodash.map@^4.5.1", 12 | "name": "lodash.map", 13 | "escapedName": "lodash.map", 14 | "rawSpec": "^4.5.1", 15 | "saveSpec": null, 16 | "fetchSpec": "^4.5.1" 17 | }, 18 | "_requiredBy": [ 19 | "/cz-conventional-changelog" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", 22 | "_shasum": "771ec7839e3473d9c4cde28b19394c3562f4f6d3", 23 | "_spec": "lodash.map@^4.5.1", 24 | "_where": "/Users/luyanli/Android/WanAndroid-Java/node_modules/cz-conventional-changelog", 25 | "author": { 26 | "name": "John-David Dalton", 27 | "email": "john.david.dalton@gmail.com", 28 | "url": "http://allyoucanleet.com/" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/lodash/lodash/issues" 32 | }, 33 | "bundleDependencies": false, 34 | "contributors": [ 35 | { 36 | "name": "John-David Dalton", 37 | "email": "john.david.dalton@gmail.com", 38 | "url": "http://allyoucanleet.com/" 39 | }, 40 | { 41 | "name": "Blaine Bublitz", 42 | "email": "blaine.bublitz@gmail.com", 43 | "url": "https://github.com/phated" 44 | }, 45 | { 46 | "name": "Mathias Bynens", 47 | "email": "mathias@qiwi.be", 48 | "url": "https://mathiasbynens.be/" 49 | } 50 | ], 51 | "deprecated": false, 52 | "description": "The lodash method `_.map` exported as a module.", 53 | "homepage": "https://lodash.com/", 54 | "icon": "https://lodash.com/icon.svg", 55 | "keywords": [ 56 | "lodash-modularized", 57 | "map" 58 | ], 59 | "license": "MIT", 60 | "name": "lodash.map", 61 | "repository": { 62 | "type": "git", 63 | "url": "git+https://github.com/lodash/lodash.git" 64 | }, 65 | "scripts": { 66 | "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" 67 | }, 68 | "version": "4.6.0" 69 | } 70 | -------------------------------------------------------------------------------- /node_modules/longest/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /node_modules/longest/README.md: -------------------------------------------------------------------------------- 1 | # longest [![NPM version](https://badge.fury.io/js/longest.svg)](http://badge.fury.io/js/longest) [![Build Status](https://travis-ci.org/jonschlinkert/longest.svg)](https://travis-ci.org/jonschlinkert/longest) 2 | 3 | > Get the longest item in an array. 4 | 5 | ## Install with [npm](npmjs.org) 6 | 7 | ```bash 8 | npm i longest --save 9 | ``` 10 | ### Install with [bower](https://github.com/bower/bower) 11 | 12 | ```bash 13 | bower install longest --save 14 | ``` 15 | 16 | ## Running tests 17 | Install dev dependencies. 18 | 19 | ```bash 20 | npm i -d && npm test 21 | ``` 22 | 23 | ## Usage 24 | 25 | ```js 26 | var longest = require('longest'); 27 | longest(['a', 'abcde', 'abc']); 28 | //=> 'abcde' 29 | 30 | longest(['a', 'abcde', 'abc']).length; 31 | //=> 5 32 | ``` 33 | 34 | ## Related projects 35 | * [longest-value](https://github.com/jonschlinkert/longest-value): Get the longest value for the given property from an array of objects. Useful for aligning values. 36 | * [right-align-values](https://github.com/jonschlinkert/right-align-values): Right align the values of a given property for each object in an array. Useful for creating text columns or tables. 37 | * [right-pad-values](https://github.com/jonschlinkert/right-pad-values): Right pad the values of a given property for each object in an array. Useful for creating text columns or tables. 38 | * [repeat-string](https://github.com/jonschlinkert/repeat-string): Repeat the given string n times. Fastest implementation for repeating a string. 39 | * [pad-right](https://github.com/jonschlinkert/pad-right): Right pad a string with zeros or a specified string. Fastest implementation. 40 | * [pad-left](https://github.com/jonschlinkert/pad-left): Left pad a string with zeros or a specified string. Fastest implementation. 41 | 42 | ## Running tests 43 | Install dev dependencies. 44 | 45 | ```bash 46 | npm i -d && npm test 47 | ``` 48 | 49 | ## Contributing 50 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/longest/issues) 51 | 52 | ## Author 53 | 54 | **Jon Schlinkert** 55 | 56 | + [github/jonschlinkert](https://github.com/jonschlinkert) 57 | + [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 58 | 59 | ## License 60 | Copyright (c) 2015 Jon Schlinkert 61 | Released under the MIT license 62 | 63 | *** 64 | 65 | _This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 31, 2015._ -------------------------------------------------------------------------------- /node_modules/longest/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * longest 3 | * 4 | * Copyright (c) 2014-2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = function(arr) { 11 | if (!arr) { 12 | return null; 13 | } 14 | 15 | var len = arr.length; 16 | if (!len) { 17 | return null; 18 | } 19 | 20 | var c = 0; 21 | var i = 0; 22 | var ele; 23 | var elen; 24 | var res; 25 | 26 | for (; i < len; i++) { 27 | ele = arr[i].toString(); 28 | elen = ele.length; 29 | 30 | if (elen > c) { 31 | res = ele; 32 | c = elen; 33 | } 34 | } 35 | 36 | return res; 37 | }; 38 | -------------------------------------------------------------------------------- /node_modules/longest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "longest@^1.0.1", 3 | "_id": "longest@1.0.1", 4 | "_inBundle": false, 5 | "_integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 6 | "_location": "/longest", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "range", 10 | "registry": true, 11 | "raw": "longest@^1.0.1", 12 | "name": "longest", 13 | "escapedName": "longest", 14 | "rawSpec": "^1.0.1", 15 | "saveSpec": null, 16 | "fetchSpec": "^1.0.1" 17 | }, 18 | "_requiredBy": [ 19 | "/cz-conventional-changelog" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 22 | "_shasum": "30a0b2da38f73770e8294a0d22e6625ed77d0097", 23 | "_spec": "longest@^1.0.1", 24 | "_where": "/Users/luyanli/Android/WanAndroid-Java/node_modules/cz-conventional-changelog", 25 | "author": { 26 | "name": "Jon Schlinkert", 27 | "url": "https://github.com/jonschlinkert" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/jonschlinkert/longest/issues" 31 | }, 32 | "bundleDependencies": false, 33 | "deprecated": false, 34 | "description": "Get the longest item in an array.", 35 | "devDependencies": { 36 | "fill-range": "^2.1.0", 37 | "mocha": "*" 38 | }, 39 | "engines": { 40 | "node": ">=0.10.0" 41 | }, 42 | "files": [ 43 | "index.js" 44 | ], 45 | "homepage": "https://github.com/jonschlinkert/longest", 46 | "keywords": [ 47 | "array", 48 | "element", 49 | "item", 50 | "long", 51 | "length", 52 | "longest" 53 | ], 54 | "license": { 55 | "type": "MIT", 56 | "url": "https://github.com/jonschlinkert/longest/blob/master/LICENSE" 57 | }, 58 | "main": "index.js", 59 | "name": "longest", 60 | "repository": { 61 | "type": "git", 62 | "url": "git+https://github.com/jonschlinkert/longest.git" 63 | }, 64 | "scripts": { 65 | "test": "mocha" 66 | }, 67 | "version": "1.0.1" 68 | } 69 | -------------------------------------------------------------------------------- /node_modules/right-pad/.npmignore: -------------------------------------------------------------------------------- 1 | ### Node ### 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # node-waf configuration 22 | .lock-wscript 23 | 24 | # Compiled binary addons (http://nodejs.org/api/addons.html) 25 | build/Release 26 | 27 | # Dependency directories 28 | node_modules 29 | jspm_packages 30 | 31 | # Optional npm cache directory 32 | .npm 33 | 34 | # Optional REPL history 35 | .node_repl_history 36 | -------------------------------------------------------------------------------- /node_modules/right-pad/README.md: -------------------------------------------------------------------------------- 1 | # Right Pad 2 | Right Pad adds a "padding" to the right side of the string with the character of your choice or just blank space. 3 | 4 | ## Install 5 | `$ npm install right-pad` 6 | 7 | ## Usage 8 | ```javascript 9 | var rightpad = require('right-pad'); 10 | rightpad('hello world', 14, '.'); // => hello world... 11 | ``` 12 | -------------------------------------------------------------------------------- /node_modules/right-pad/examples/basic.js: -------------------------------------------------------------------------------- 1 | // Coding standard for this project defined @ https://github.com/MatthewSH/standards/blob/master/JavaScript.md 2 | const $rightpad = require('../rightpad'); 3 | 4 | console.log($rightpad('hello world', 14, '.')); // => hello world... 5 | -------------------------------------------------------------------------------- /node_modules/right-pad/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "right-pad@^1.0.1", 3 | "_id": "right-pad@1.0.1", 4 | "_inBundle": false, 5 | "_integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=", 6 | "_location": "/right-pad", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "range", 10 | "registry": true, 11 | "raw": "right-pad@^1.0.1", 12 | "name": "right-pad", 13 | "escapedName": "right-pad", 14 | "rawSpec": "^1.0.1", 15 | "saveSpec": null, 16 | "fetchSpec": "^1.0.1" 17 | }, 18 | "_requiredBy": [ 19 | "/cz-conventional-changelog" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", 22 | "_shasum": "8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0", 23 | "_spec": "right-pad@^1.0.1", 24 | "_where": "/Users/luyanli/Android/WanAndroid-Java/node_modules/cz-conventional-changelog", 25 | "author": { 26 | "name": "matthewh", 27 | "email": "hello@matthewh.in", 28 | "url": "http://matthewh.in/" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/MatthewNPM/right-pad/issues" 32 | }, 33 | "bundleDependencies": false, 34 | "deprecated": false, 35 | "description": "Right Pad adds a padding to the right side of the string with the character of your choice or just blank space.", 36 | "engines": { 37 | "node": ">= 0.10" 38 | }, 39 | "homepage": "https://github.com/MatthewNPM/right-pad", 40 | "keywords": [ 41 | "right", 42 | "pad", 43 | "string" 44 | ], 45 | "license": "MIT", 46 | "main": "rightpad.js", 47 | "name": "right-pad", 48 | "private": false, 49 | "repository": { 50 | "type": "git", 51 | "url": "git+https://github.com/MatthewNPM/right-pad.git" 52 | }, 53 | "scripts": { 54 | "test": "echo \"Error: no test specified\" && exit 1" 55 | }, 56 | "version": "1.0.1" 57 | } 58 | -------------------------------------------------------------------------------- /node_modules/right-pad/rightpad.js: -------------------------------------------------------------------------------- 1 | // Coding standard for this project defined @ https://github.com/MatthewSH/standards/blob/master/JavaScript.md 2 | 'use strict'; 3 | 4 | exports = module.exports = function rightPad (_string, _length, _char) { 5 | if (typeof _string !== 'string') { 6 | throw new Error('The string parameter must be a string.'); 7 | } 8 | if (_string.length < 1) { 9 | throw new Error('The string parameter must be 1 character or longer.'); 10 | } 11 | if (typeof _length !== 'number') { 12 | throw new Error('The length parameter must be a number.'); 13 | } 14 | if(typeof _char !== 'string' && _char) { 15 | throw new Error('The character parameter must be a string.'); 16 | } 17 | 18 | var i = -1; 19 | _length = _length - _string.length; 20 | if (!_char && _char !== 0) { 21 | _char = ' '; 22 | } 23 | while (++i < _length) { 24 | _string += _char; 25 | } 26 | 27 | return _string; 28 | } 29 | -------------------------------------------------------------------------------- /node_modules/word-wrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2017, Jon Schlinkert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /node_modules/word-wrap/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Wrap words to a specified length. 3 | */ 4 | export = wrap; 5 | 6 | declare function wrap(str: string, options?: wrap.IOptions): string; 7 | 8 | declare namespace wrap { 9 | export interface IOptions { 10 | 11 | /** 12 | * The width of the text before wrapping to a new line. 13 | * @default ´50´ 14 | */ 15 | width?: number; 16 | 17 | /** 18 | * The string to use at the beginning of each line. 19 | * @default ´ ´ (two spaces) 20 | */ 21 | indent?: string; 22 | 23 | /** 24 | * The string to use at the end of each line. 25 | * @default ´\n´ 26 | */ 27 | newline?: string; 28 | 29 | /** 30 | * An escape function to run on each line after splitting them. 31 | * @default (str: string) => string; 32 | */ 33 | escape?: (str: string) => string; 34 | 35 | /** 36 | * Trim trailing whitespace from the returned string. 37 | * This option is included since .trim() would also strip 38 | * the leading indentation from the first line. 39 | * @default true 40 | */ 41 | trim?: boolean; 42 | 43 | /** 44 | * Break a word between any two letters when the word is longer 45 | * than the specified width. 46 | * @default false 47 | */ 48 | cut?: boolean; 49 | } 50 | } -------------------------------------------------------------------------------- /node_modules/word-wrap/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * word-wrap 3 | * 4 | * Copyright (c) 2014-2017, Jon Schlinkert. 5 | * Released under the MIT License. 6 | */ 7 | 8 | module.exports = function(str, options) { 9 | options = options || {}; 10 | if (str == null) { 11 | return str; 12 | } 13 | 14 | var width = options.width || 50; 15 | var indent = (typeof options.indent === 'string') 16 | ? options.indent 17 | : ' '; 18 | 19 | var newline = options.newline || '\n' + indent; 20 | var escape = typeof options.escape === 'function' 21 | ? options.escape 22 | : identity; 23 | 24 | var regexString = '.{1,' + width + '}'; 25 | if (options.cut !== true) { 26 | regexString += '([\\s\u200B]+|$)|[^\\s\u200B]+?([\\s\u200B]+|$)'; 27 | } 28 | 29 | var re = new RegExp(regexString, 'g'); 30 | var lines = str.match(re) || []; 31 | var result = indent + lines.map(function(line) { 32 | if (line.slice(-1) === '\n') { 33 | line = line.slice(0, line.length - 1); 34 | } 35 | return escape(line); 36 | }).join(newline); 37 | 38 | if (options.trim === true) { 39 | result = result.replace(/[ \t]*$/gm, ''); 40 | } 41 | return result; 42 | }; 43 | 44 | function identity(str) { 45 | return str; 46 | } 47 | -------------------------------------------------------------------------------- /node_modules/word-wrap/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "word-wrap@^1.0.3", 3 | "_id": "word-wrap@1.2.3", 4 | "_inBundle": false, 5 | "_integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 6 | "_location": "/word-wrap", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "range", 10 | "registry": true, 11 | "raw": "word-wrap@^1.0.3", 12 | "name": "word-wrap", 13 | "escapedName": "word-wrap", 14 | "rawSpec": "^1.0.3", 15 | "saveSpec": null, 16 | "fetchSpec": "^1.0.3" 17 | }, 18 | "_requiredBy": [ 19 | "/cz-conventional-changelog" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 22 | "_shasum": "610636f6b1f703891bd34771ccb17fb93b47079c", 23 | "_spec": "word-wrap@^1.0.3", 24 | "_where": "/Users/luyanli/Android/WanAndroid-Java/node_modules/cz-conventional-changelog", 25 | "author": { 26 | "name": "Jon Schlinkert", 27 | "url": "https://github.com/jonschlinkert" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/jonschlinkert/word-wrap/issues" 31 | }, 32 | "bundleDependencies": false, 33 | "contributors": [ 34 | { 35 | "name": "Danilo Sampaio", 36 | "email": "danilo.sampaio@gmail.com", 37 | "url": "localhost:8080" 38 | }, 39 | { 40 | "name": "Fede Ramirez", 41 | "email": "i@2fd.me", 42 | "url": "https://2fd.github.io" 43 | }, 44 | { 45 | "name": "Joe Hildebrand", 46 | "email": "joe-github@cursive.net", 47 | "url": "https://twitter.com/hildjj" 48 | }, 49 | { 50 | "name": "Jon Schlinkert", 51 | "email": "jon.schlinkert@sellside.com", 52 | "url": "http://twitter.com/jonschlinkert" 53 | }, 54 | { 55 | "name": "Todd Kennedy", 56 | "url": "https://tck.io" 57 | }, 58 | { 59 | "name": "Waldemar Reusch", 60 | "url": "https://github.com/lordvlad" 61 | }, 62 | { 63 | "name": "Wolfgang Faust", 64 | "url": "http://www.linestarve.com" 65 | }, 66 | { 67 | "name": "Zach Hale", 68 | "email": "zachhale@gmail.com", 69 | "url": "http://zachhale.com" 70 | } 71 | ], 72 | "deprecated": false, 73 | "description": "Wrap words to a specified length.", 74 | "devDependencies": { 75 | "gulp-format-md": "^0.1.11", 76 | "mocha": "^3.2.0" 77 | }, 78 | "engines": { 79 | "node": ">=0.10.0" 80 | }, 81 | "files": [ 82 | "index.js", 83 | "index.d.ts" 84 | ], 85 | "homepage": "https://github.com/jonschlinkert/word-wrap", 86 | "keywords": [ 87 | "break", 88 | "carriage", 89 | "line", 90 | "new-line", 91 | "newline", 92 | "return", 93 | "soft", 94 | "text", 95 | "word", 96 | "word-wrap", 97 | "words", 98 | "wrap" 99 | ], 100 | "license": "MIT", 101 | "main": "index.js", 102 | "name": "word-wrap", 103 | "repository": { 104 | "type": "git", 105 | "url": "git+https://github.com/jonschlinkert/word-wrap.git" 106 | }, 107 | "scripts": { 108 | "test": "mocha" 109 | }, 110 | "typings": "index.d.ts", 111 | "verb": { 112 | "toc": false, 113 | "layout": "default", 114 | "tasks": [ 115 | "readme" 116 | ], 117 | "plugins": [ 118 | "gulp-format-md" 119 | ], 120 | "lint": { 121 | "reflinks": true 122 | }, 123 | "related": { 124 | "list": [ 125 | "common-words", 126 | "shuffle-words", 127 | "unique-words", 128 | "wordcount" 129 | ] 130 | }, 131 | "reflinks": [ 132 | "verb", 133 | "verb-generate-readme" 134 | ] 135 | }, 136 | "version": "1.2.3" 137 | } 138 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wanandroid-java", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "conventional-commit-types": { 8 | "version": "2.2.0", 9 | "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-2.2.0.tgz", 10 | "integrity": "sha1-XblXOdbCEqy+e29lahG5QLqmiUY=", 11 | "dev": true 12 | }, 13 | "cz-conventional-changelog": { 14 | "version": "2.1.0", 15 | "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz", 16 | "integrity": "sha1-L0vHOQ4yROTfKT5ro1Hkx0Cnx2Q=", 17 | "dev": true, 18 | "requires": { 19 | "conventional-commit-types": "^2.0.0", 20 | "lodash.map": "^4.5.1", 21 | "longest": "^1.0.1", 22 | "right-pad": "^1.0.1", 23 | "word-wrap": "^1.0.3" 24 | } 25 | }, 26 | "lodash.map": { 27 | "version": "4.6.0", 28 | "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", 29 | "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", 30 | "dev": true 31 | }, 32 | "longest": { 33 | "version": "1.0.1", 34 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 35 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 36 | "dev": true 37 | }, 38 | "right-pad": { 39 | "version": "1.0.1", 40 | "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", 41 | "integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=", 42 | "dev": true 43 | }, 44 | "word-wrap": { 45 | "version": "1.2.3", 46 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 47 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 48 | "dev": true 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wanandroid-java", 3 | "version": "1.0.0", 4 | "description": "wanandroid-java", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/chongyucaiyan/WanAndroid-Java.git" 12 | }, 13 | "author": "chongyucaiyan", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/chongyucaiyan/WanAndroid-Java/issues" 17 | }, 18 | "homepage": "https://github.com/chongyucaiyan/WanAndroid-Java#readme", 19 | "devDependencies": { 20 | "cz-conventional-changelog": "^2.1.0" 21 | }, 22 | "config": { 23 | "commitizen": { 24 | "path": "./node_modules/cz-conventional-changelog" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /screenshots/01-Homepage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/screenshots/01-Homepage.jpg -------------------------------------------------------------------------------- /screenshots/02-System.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/screenshots/02-System.jpg -------------------------------------------------------------------------------- /screenshots/03-WeChat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/screenshots/03-WeChat.jpg -------------------------------------------------------------------------------- /screenshots/04-Navigation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/screenshots/04-Navigation.jpg -------------------------------------------------------------------------------- /screenshots/05-Project.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chongyucaiyan/WanAndroid-Java/1c8d427c8deaa18163df6eaf543bae8cef01d587/screenshots/05-Project.jpg -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------