├── .gitignore ├── README.md ├── app ├── .gitignore ├── bugly │ ├── BuglySymtabLog.txt │ └── BuglyUploadLog.txt ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── lyl │ │ └── boon │ │ ├── app │ │ ├── Constant.java │ │ └── MyApp.java │ │ ├── net │ │ ├── LeanCloudNet.kt │ │ ├── Network.java │ │ ├── api │ │ │ ├── WanAndroidApi.java │ │ │ ├── ZhaiNanApi.java │ │ │ └── ZhuangbiApi.java │ │ ├── entity │ │ │ ├── BaseEntity.java │ │ │ ├── FavoriteEntity.kt │ │ │ ├── SuperGalleryEntity.java │ │ │ ├── SuperImageEntity.java │ │ │ ├── SuperMenuEntity.java │ │ │ ├── UserInfoEntity.kt │ │ │ ├── WanAndroidEntity.java │ │ │ └── ZhuangbiEntity.java │ │ └── model │ │ │ └── UserModel.kt │ │ ├── ui │ │ ├── AboutActivity.java │ │ ├── MainActivity.java │ │ ├── MainViewPageAdpater.java │ │ ├── account │ │ │ ├── LoginActivity.kt │ │ │ └── RegisterActivity.kt │ │ ├── base │ │ │ ├── BaseActivity.java │ │ │ ├── BaseFragment.java │ │ │ ├── apdter │ │ │ │ └── MyBaseAdapter.java │ │ │ └── fragment │ │ │ │ ├── BaseMenuFragment.java │ │ │ │ └── BaseRecyclerFragment.java │ │ ├── favorite │ │ │ ├── FavoriteActivity.kt │ │ │ ├── FavoriteAdapter.kt │ │ │ └── FavoriteFragment.java │ │ ├── image │ │ │ ├── ImageActivity.java │ │ │ └── ImageAdapter.java │ │ ├── joke │ │ │ ├── JokeFragment.java │ │ │ └── JokeListAdapter.java │ │ ├── learn │ │ │ ├── DevelopAdapter.java │ │ │ ├── LearnFragment.java │ │ │ └── LearnListFragment.java │ │ ├── superboon │ │ │ ├── SuperBoonFragment.java │ │ │ ├── SuperBoonListAdapter.java │ │ │ ├── SuperBoonListFragment.java │ │ │ ├── SuperGalleryActivity.java │ │ │ ├── SuperGalleryAdapter.java │ │ │ └── SuperGalleryFragment.java │ │ ├── wanandroid │ │ │ ├── WanAndroidAdapter.java │ │ │ └── WanAndroidFragment.java │ │ ├── web │ │ │ └── Html5Activity.java │ │ └── young │ │ │ ├── YongAdapter.java │ │ │ └── YoungFragment.java │ │ ├── utils │ │ ├── DateUtils.java │ │ ├── FileUtils.java │ │ ├── ImgUtils.java │ │ ├── LogUtil.java │ │ ├── MyUtils.java │ │ ├── NetStatusUtil.java │ │ └── SPUtils.java │ │ └── view │ │ ├── HackyViewPager.java │ │ ├── behavior │ │ ├── BottomNavigationBehavior.java │ │ └── VerticalScrollingBehavior.java │ │ ├── loading │ │ ├── LoadingView.java │ │ └── ShapeLoadingView.java │ │ └── recycler │ │ ├── LinearLayoutManagerWrapper.java │ │ └── OnRecycleViewScrollListener.java │ └── res │ ├── anim │ ├── fade_in.xml │ ├── fade_out.xml │ ├── slide_down_in.xml │ ├── slide_down_out.xml │ ├── slide_right_to_left.xml │ ├── slide_up_in.xml │ └── slide_up_out.xml │ ├── drawable-hdpi │ ├── ic_android_black_24dp.png │ ├── ic_back.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_phone_android_black_24dp.png │ ├── ic_pregnant_woman_black_24dp.png │ ├── ic_sentiment_very_satisfied_black_24dp.png │ ├── ic_share_black_24dp.png │ └── ic_wc_black_24dp.png │ ├── drawable-mdpi │ ├── ic_android_black_24dp.png │ ├── ic_back.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_phone_android_black_24dp.png │ ├── ic_pregnant_woman_black_24dp.png │ ├── ic_sentiment_very_satisfied_black_24dp.png │ ├── ic_share_black_24dp.png │ └── ic_wc_black_24dp.png │ ├── drawable-xhdpi │ ├── error_data.png │ ├── error_img.jpg │ ├── error_img1.jpeg │ ├── ic_android_black_24dp.png │ ├── ic_back.png │ ├── ic_favorite.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_launcher.png │ ├── ic_phone_android_black_24dp.png │ ├── ic_pregnant_woman_black_24dp.png │ ├── ic_sentiment_very_satisfied_black_24dp.png │ ├── ic_share_black_24dp.png │ ├── ic_wc_black_24dp.png │ └── logo.png │ ├── drawable-xxhdpi │ ├── ic_android_black_24dp.png │ ├── ic_back.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_more.png │ ├── ic_phone_android_black_24dp.png │ ├── ic_pregnant_woman_black_24dp.png │ ├── ic_sentiment_very_satisfied_black_24dp.png │ ├── ic_share_black_24dp.png │ └── ic_wc_black_24dp.png │ ├── drawable-xxxhdpi │ ├── ic_android_black_24dp.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_phone_android_black_24dp.png │ ├── ic_pregnant_woman_black_24dp.png │ ├── ic_sentiment_very_satisfied_black_24dp.png │ ├── ic_share_black_24dp.png │ └── ic_wc_black_24dp.png │ ├── drawable │ ├── bg_gary.xml │ ├── selector_gary.xml │ └── shadow.xml │ ├── layout │ ├── action_bar_title.xml │ ├── activity_about.xml │ ├── activity_favorite.xml │ ├── activity_image.xml │ ├── activity_login.xml │ ├── activity_main.xml │ ├── activity_register.xml │ ├── activity_super_gallery.xml │ ├── activity_web.xml │ ├── fragment_base.xml │ ├── fragment_list.xml │ ├── item_develop.xml │ ├── item_favorite.xml │ ├── item_grid.xml │ ├── item_header.xml │ ├── item_image_h.xml │ ├── item_image_show.xml │ ├── item_image_v.xml │ └── load_view.xml │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── loading_arrt.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ ├── bottombar_menu.xml │ └── network_security_config.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── img ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png ├── lyl.jks ├── settings.gradle └── shadowsocks-libev.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .DS_Store 5 | /build 6 | /captures 7 | /app/bugly/ 8 | /.idea 9 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # boon 2 | 移动开发者福利App 3 | 4 | 自己做的一个小练习。 5 | 第一个 tab 是 大佬公众号 的文章,第二个是 WanAndroid 的, 6 | 后面的都是福利,满满的福利。 7 | 8 | ### [App 下载地址](http://betaqa.lylyl.cn/ymup) 9 | 10 | 11 | ![](https://github.com/Wing-Li/boon/blob/master/img/1.png) 12 | ![](https://github.com/Wing-Li/boon/blob/master/img/2.png) 13 | ![](https://github.com/Wing-Li/boon/blob/master/img/3.png) 14 | ![](https://github.com/Wing-Li/boon/blob/master/img/4.png) 15 | 16 | 你猜为什么没有第五个 Page 的图? 17 | 想知道吗? 18 | 19 | 20 | [shadowsocks-libev 配置](https://github.com/Wing-Li/boon/blob/master/shadowsocks-libev.md), 21 | 国内好多网站都发不了,暂时放这里。 22 | 23 | 24 | [搭建SSR/SS服务端教程 (安装器)](https://viencoding.com/article/122) 25 | 26 | [搭建v2ray(安装器,安装非常方便)](https://viencoding.com/article/207) 27 | 28 | [V2Ray客户端](https://tlanyan.me/v2ray-clients-download/) 29 | 30 | ## License 31 | 32 | MIT License 33 | 34 | Copyright (c) 2016 Wing-Li 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy 37 | of this software and associated documentation files (the "Software"), to deal 38 | in the Software without restriction, including without limitation the rights 39 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 40 | copies of the Software, and to permit persons to whom the Software is 41 | furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all 44 | copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 49 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 52 | SOFTWARE. 53 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/bugly/BuglySymtabLog.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wing-Li/boon/c3d93fb37ac38af5044ba17fa7e04067c9ec6bec/app/bugly/BuglySymtabLog.txt -------------------------------------------------------------------------------- /app/bugly/BuglyUploadLog.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wing-Li/boon/c3d93fb37ac38af5044ba17fa7e04067c9ec6bec/app/bugly/BuglyUploadLog.txt -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-parcelize' 4 | apply plugin: 'kotlin-kapt' 5 | 6 | //加载资源.在本地的 local.properties 文件设置了一些参数,从这里获取 7 | Properties properties = new Properties() 8 | InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream(); 9 | properties.load(inputStream) 10 | 11 | repositories { 12 | maven { url "https://jitpack.io" } 13 | } 14 | 15 | android { 16 | compileSdk = 34 17 | 18 | compileOptions { 19 | sourceCompatibility JavaVersion.VERSION_11 20 | targetCompatibility JavaVersion.VERSION_11 21 | } 22 | kotlinOptions { 23 | jvmTarget = '11' 24 | } 25 | 26 | // 签名文件 27 | signingConfigs { 28 | config { 29 | keyAlias 'lyl' 30 | keyPassword '123456' 31 | storeFile file('../lyl.jks') 32 | storePassword '123456' 33 | } 34 | } 35 | 36 | sourceSets { 37 | main { 38 | jniLibs.srcDirs = ['libs'] 39 | } 40 | } 41 | 42 | defaultConfig { 43 | applicationId "com.lyl.boon" 44 | minSdk = 21 45 | targetSdk = 34 46 | versionCode 6 47 | versionName "1.6.0" 48 | multiDexEnabled true 49 | flavorDimensions "App" 50 | ndk { 51 | abiFilters "armeabi-v7a", "arm64-v8a" // // , "armeabi", "x86", "x86_64" 52 | } 53 | } 54 | 55 | dataBinding { 56 | enabled = true 57 | } 58 | 59 | // 多渠道/多环境 的不同配置 60 | productFlavors { 61 | dev { 62 | // 每个环境包名不同 63 | applicationId "com.lyl.boon.dev" 64 | // 动态添加 string.xml 字段; 65 | // 注意,这里是添加,在 string.xml 不能有这个字段,会重名!!! 66 | resValue "string", "app_name", "dev_boon" 67 | resValue "bool", "isrRank", 'false' 68 | // 动态修改 常量 字段 69 | buildConfigField "String", "ENVIRONMENT", '"dev"' 70 | buildConfigField "String", "BUGLYAPPID", properties.getProperty('appIdMark') 71 | buildConfigField "String", "LEANCLOUD_APPID", properties.getProperty('leancloudAppId') 72 | buildConfigField "String", "LEANCLOUD_APPKEY", properties.getProperty('leancloudAppKey') 73 | // 修改 AndroidManifest.xml 里渠道变量 74 | manifestPlaceholders = [UMENG_CHANNEL_VALUE: "dev", 75 | app_icon : "@drawable/ic_launcher"] 76 | 77 | dimension "App" 78 | } 79 | stage { 80 | applicationId "com.lyl.boon.stage" 81 | 82 | resValue "string", "app_name", "stage_boon" 83 | resValue "bool", "isrRank", 'true' 84 | 85 | buildConfigField "String", "ENVIRONMENT", '"stage"' 86 | buildConfigField "String", "BUGLYAPPID", properties.getProperty('appIdMark') 87 | buildConfigField "String", "LEANCLOUD_APPID", properties.getProperty('leancloudAppId') 88 | buildConfigField "String", "LEANCLOUD_APPKEY", properties.getProperty('leancloudAppKey') 89 | 90 | manifestPlaceholders = [UMENG_CHANNEL_VALUE: "stage", 91 | app_icon : "@drawable/logo"] 92 | 93 | dimension "App" 94 | } 95 | prod { 96 | applicationId "com.lyl.boon" 97 | 98 | resValue "string", "app_name", "boon" 99 | resValue "bool", "isrRank", 'true' 100 | 101 | buildConfigField "String", "ENVIRONMENT", '"prod"' 102 | buildConfigField "String", "BUGLYAPPID", properties.getProperty('appIdMark') 103 | buildConfigField "String", "LEANCLOUD_APPID", properties.getProperty('leancloudAppId') 104 | buildConfigField "String", "LEANCLOUD_APPKEY", properties.getProperty('leancloudAppKey') 105 | 106 | manifestPlaceholders = [UMENG_CHANNEL_VALUE: "prod", 107 | app_icon : "@drawable/logo"] 108 | 109 | dimension "App" 110 | } 111 | } 112 | 113 | //移除lint检测的error 114 | lintOptions { 115 | abortOnError false 116 | } 117 | 118 | buildTypes { 119 | debug { 120 | signingConfig signingConfigs.config 121 | } 122 | 123 | release { 124 | minifyEnabled false 125 | zipAlignEnabled true 126 | //移除无用的resource文件 127 | shrinkResources false 128 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 129 | signingConfig signingConfigs.config 130 | 131 | // 批量打包 132 | applicationVariants.all { variant -> 133 | variant.outputs.all { 134 | outputFileName = "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${releaseTime()}.apk" 135 | } 136 | } 137 | } 138 | } 139 | } 140 | 141 | static def releaseTime() { 142 | return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) 143 | } 144 | 145 | dependencies { 146 | implementation fileTree(dir: 'libs', include: ['*.jar']) 147 | 148 | implementation 'com.android.support:multidex:1.0.3' 149 | implementation 'com.google.android.material:material:1.11.0' 150 | implementation 'androidx.appcompat:appcompat:1.6.1' 151 | implementation 'androidx.recyclerview:recyclerview:1.3.2' 152 | implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' 153 | implementation 'androidx.cardview:cardview:1.0.0' 154 | implementation 'com.google.code.gson:gson:2.10.1' 155 | implementation 'com.squareup.okhttp3:okhttp:4.11.0' 156 | implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3' 157 | implementation 'com.jakewharton:butterknife:7.0.1' 158 | annotationProcessor 'com.jakewharton:butterknife:7.0.1' 159 | implementation 'com.github.bumptech.glide:glide:4.15.1' 160 | implementation 'com.commit451:PhotoView:1.2.5' 161 | implementation 'com.jaeger.statusbarutil:library:1.5.1' 162 | implementation 'com.roughike:bottom-bar:2.3.1' 163 | //Material Dialog 164 | implementation 'me.drakeet.materialdialog:library:1.3.1' 165 | 166 | implementation 'com.squareup.retrofit2:retrofit:2.9.0' 167 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0' 168 | implementation 'com.squareup.retrofit2:adapter-rxjava:2.2.0' 169 | 170 | implementation 'io.reactivex:rxjava:1.2.3' 171 | implementation 'io.reactivex:rxandroid:1.2.1' 172 | 173 | implementation 'com.github.githubwing:ByeBurger:1.2.3' 174 | //一个不错的BaseAapter封装类 175 | implementation 'org.byteam.superadapter:superadapter:3.4' 176 | 177 | //非常不错的 loading 加载库 178 | implementation 'com.wang.avi:library:1.0.5' 179 | implementation 'com.nineoldandroids:library:2.4.0' 180 | //应用升级 181 | implementation 'com.tencent.bugly:crashreport_upgrade:1.4.2' 182 | implementation 'com.tencent.bugly:nativecrashreport:3.7.1' 183 | 184 | implementation 'cn.leancloud:storage-android:6.1.1' 185 | implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' 186 | 187 | implementation 'org.jsoup:jsoup:1.17.2' 188 | } 189 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 49 | 50 | 53 | 56 | 59 | 62 | 65 | 68 | 71 | 72 | 73 | 74 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/app/Constant.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.app; 2 | 3 | import com.lyl.boon.BuildConfig; 4 | 5 | /** 6 | * Wing_Li 7 | * 2016/4/7. 8 | */ 9 | public class Constant { 10 | 11 | /** 12 | * 这里是从 Gradle 设置的 13 | */ 14 | public static final String ENVIRONMENT = BuildConfig.ENVIRONMENT; 15 | 16 | /** 17 | * 启动HTML页面的名称 18 | */ 19 | public static final String WEB_NAME = "com.lyl.boon.ui.activity.htmlactivity"; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/app/MyApp.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.app; 2 | 3 | import android.os.Environment; 4 | import android.text.TextUtils; 5 | 6 | import androidx.multidex.MultiDexApplication; 7 | 8 | import com.lyl.boon.BuildConfig; 9 | import com.tencent.bugly.Bugly; 10 | import com.tencent.bugly.crashreport.CrashReport; 11 | 12 | import java.io.File; 13 | 14 | import cn.leancloud.AVOSCloud; 15 | 16 | /** 17 | * Wing_Li 18 | * 2016/3/31. 19 | */ 20 | public class MyApp extends MultiDexApplication { 21 | 22 | /** 23 | * App 存放文件的路径 24 | **/ 25 | private static String mAppPath; 26 | 27 | @Override 28 | public void onCreate() { 29 | super.onCreate(); 30 | initBugly(); 31 | initLeanCloud(); 32 | } 33 | 34 | /** 35 | * 初始化 leancloud 36 | */ 37 | private void initLeanCloud() { 38 | AVOSCloud.initialize(this, BuildConfig.LEANCLOUD_APPID, BuildConfig.LEANCLOUD_APPKEY, "https://boon.lylyl.cn"); 39 | } 40 | 41 | /** 42 | * 初始化BUG分析 和 应用升级检测 43 | */ 44 | private void initBugly() { 45 | String buglyAppId = BuildConfig.BUGLYAPPID; 46 | if (!TextUtils.isEmpty(buglyAppId)) { 47 | CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(getApplicationContext()); 48 | strategy.setAppReportDelay(60000); 49 | Bugly.init(getApplicationContext(), buglyAppId, true, strategy); 50 | } 51 | } 52 | 53 | /** 54 | * 获取存放文件的了路径 55 | */ 56 | public static String getAppPath() { 57 | if (!TextUtils.isEmpty(mAppPath)) { 58 | return mAppPath; 59 | } 60 | File sdCard = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoluteFile(); 61 | File file = new File(sdCard, "boon"); 62 | if (!file.exists()) { 63 | file.mkdirs(); 64 | } 65 | mAppPath = file.getAbsolutePath(); 66 | return mAppPath; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/Network.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.lyl.boon.BuildConfig; 6 | import com.lyl.boon.net.api.WanAndroidApi; 7 | import com.lyl.boon.net.api.ZhaiNanApi; 8 | import com.lyl.boon.net.api.ZhuangbiApi; 9 | 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import okhttp3.OkHttpClient; 13 | import okhttp3.logging.HttpLoggingInterceptor; 14 | import retrofit2.Retrofit; 15 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; 16 | import retrofit2.converter.gson.GsonConverterFactory; 17 | 18 | /** 19 | * Wing_Li 20 | * 2016/3/30. 21 | */ 22 | public class Network { 23 | 24 | /** 25 | * 玩Android请求的地址 26 | **/ 27 | private static final String URL_WANANDROID = "http://www.wanandroid.com/"; 28 | /** 29 | * 装逼图片地址 30 | */ 31 | private static final String URL_ZHUANG = "http://www.zhuangbi.info/"; 32 | 33 | /** 34 | * 设置超时的时间 35 | **/ 36 | private static final int DEFAULT_TIMEOUT = 5; 37 | 38 | private static OkHttpClient.Builder httpClientBuilder; 39 | private static WanAndroidApi wanAndroidApi; 40 | private static ZhuangbiApi zhuangbiApi; 41 | private static ZhaiNanApi zhaiNanApi; 42 | 43 | 44 | private Network() { 45 | } 46 | 47 | /** 48 | * 初始化 OkHttp 49 | */ 50 | private static void initOkHttp() { 51 | httpClientBuilder = new OkHttpClient.Builder(); 52 | httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); 53 | 54 | // devCompile 'com.squareup.okhttp3:logging-interceptor:3.8.0' 55 | // compile 'com.squareup.okhttp3:okhttp:3.8.0' 56 | if ("dev".equals(BuildConfig.ENVIRONMENT)) { 57 | HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); 58 | logging.setLevel(HttpLoggingInterceptor.Level.BODY); 59 | httpClientBuilder.addInterceptor(logging); 60 | } 61 | } 62 | 63 | /** 64 | * 获取 玩Android 请求的操作。 65 | */ 66 | public static WanAndroidApi getWanAndroidList() { 67 | if (wanAndroidApi == null) { 68 | wanAndroidApi = getRetrofit(URL_WANANDROID).create(WanAndroidApi.class); 69 | } 70 | return wanAndroidApi; 71 | } 72 | 73 | /** 74 | * 装逼图片的接口 75 | */ 76 | public static ZhuangbiApi getZhuangbi() { 77 | if (zhuangbiApi == null) { 78 | zhuangbiApi = getRetrofit(URL_ZHUANG).create(ZhuangbiApi.class); 79 | } 80 | return zhuangbiApi; 81 | } 82 | 83 | /** 84 | * 宅男女神的接口 85 | */ 86 | public static ZhaiNanApi getZhaiNanApi() { 87 | if (zhaiNanApi == null) { 88 | zhaiNanApi = new ZhaiNanApi(); 89 | } 90 | return zhaiNanApi; 91 | } 92 | 93 | @NonNull 94 | private static Retrofit getRetrofit(String url) { 95 | if (httpClientBuilder == null) { 96 | initOkHttp(); 97 | } 98 | return new Retrofit.Builder()// 99 | .client(httpClientBuilder.build())// 100 | .baseUrl(url)// 101 | .addConverterFactory(GsonConverterFactory.create())// 102 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create())// 103 | .build(); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/api/WanAndroidApi.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.api; 2 | 3 | import com.lyl.boon.net.entity.WanAndroidEntity; 4 | 5 | import retrofit2.http.GET; 6 | import retrofit2.http.Path; 7 | import rx.Observable; 8 | 9 | /** 10 | * Wing_Li 11 | * 2016/3/30. 12 | */ 13 | public interface WanAndroidApi { 14 | 15 | @GET("article/list/{page}/json") 16 | Observable getWanAndroidList(@Path("page") int page); 17 | 18 | @GET("wxarticle/list/{id}/{page}/json") 19 | Observable getWxArticleList(@Path("id") String id, @Path("page") int page); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/api/ZhaiNanApi.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.api; 2 | 3 | import com.lyl.boon.net.entity.SuperGalleryEntity; 4 | import com.lyl.boon.net.entity.SuperImageEntity; 5 | 6 | import org.jsoup.Jsoup; 7 | import org.jsoup.nodes.Document; 8 | import org.jsoup.nodes.Element; 9 | import org.jsoup.select.Elements; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import rx.Observable; 15 | 16 | /** 17 | * 宅男女神 18 | * https://www.haonvshen.com/ 19 | */ 20 | public class ZhaiNanApi { 21 | 22 | private String baseUrl = "https://www.haonvshen.com/"; 23 | 24 | public Observable getGalleryList(String type, int page) { 25 | return Observable.create(subscriber -> { 26 | SuperGalleryEntity superGalleryEntity = new SuperGalleryEntity(); 27 | List listBeanList = new ArrayList<>(); 28 | 29 | try { 30 | String url = ""; 31 | if (page <= 1) { 32 | url = baseUrl + "tags/" + type + ".html"; 33 | } else { 34 | url = baseUrl + "tags/" + type + "_" + page + ".html"; 35 | } 36 | Document document = Jsoup.connect(url).get(); 37 | Elements galleryList = document.select("div#listdiv ul li"); 38 | 39 | SuperGalleryEntity.ListBean listBean; 40 | for (Element gallery : galleryList) { 41 | listBean = new SuperGalleryEntity.ListBean(); 42 | Element link = gallery.selectFirst("div.galleryli_div a"); 43 | Element img = gallery.selectFirst("div.galleryli_div img"); 44 | 45 | String imageUrl = img.attr("data-original").replace("httpS://", "https://"); 46 | 47 | listBean.setUrl(link.attr("href")); // https://www.haonvshen.com/gallery/25662.html 48 | listBean.setGroup_title(img.attr("title")); 49 | listBean.setQhimg_thumb_url(imageUrl); 50 | listBean.setQhimg_url(imageUrl); 51 | listBean.setQhimg_width(528); 52 | listBean.setQhimg_height(2210); 53 | listBeanList.add(listBean); 54 | } 55 | 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | subscriber.onError(e); 59 | } 60 | 61 | superGalleryEntity.setList(listBeanList); 62 | subscriber.onNext(superGalleryEntity); 63 | }); 64 | } 65 | 66 | public Observable getGalleryInfo(String detailsUrl, int page) { 67 | return Observable.create(subscriber -> { 68 | SuperImageEntity superImageEntity = new SuperImageEntity(); 69 | List listBeanList = new ArrayList<>(); 70 | 71 | try { 72 | String url = ""; 73 | if (page <= 1) { 74 | url = detailsUrl; // https://www.haonvshen.com/gallery/25662.html 75 | } else { 76 | url = detailsUrl.replace(".html", "_" + page + ".html"); // https://www.haonvshen.com/gallery/25662_2.html 77 | } 78 | 79 | Document document = Jsoup.connect(url).get(); 80 | Elements imgs = document.select("div#high ul img"); 81 | 82 | SuperImageEntity.ListBean listBean; 83 | for (Element img : imgs) { 84 | listBean = new SuperImageEntity.ListBean(); 85 | 86 | String imageUrl = img.attr("src"); 87 | listBean.setPic_url(imageUrl); 88 | listBean.setQhimg_url(imageUrl); 89 | listBean.setQhimg_thumb_url(imageUrl); 90 | listBeanList.add(listBean); 91 | } 92 | 93 | } catch (Exception e) { 94 | e.printStackTrace(); 95 | subscriber.onError(e); 96 | } 97 | 98 | superImageEntity.setList(listBeanList); 99 | subscriber.onNext(superImageEntity); 100 | }); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/api/ZhuangbiApi.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.api; 2 | 3 | 4 | import com.lyl.boon.net.entity.ZhuangbiEntity; 5 | 6 | import java.util.List; 7 | 8 | import okhttp3.ResponseBody; 9 | import retrofit2.Call; 10 | import retrofit2.http.GET; 11 | import retrofit2.http.Query; 12 | import retrofit2.http.Url; 13 | import rx.Observable; 14 | 15 | /** 16 | * Wing_Li 17 | * 2016/4/15. 18 | */ 19 | public interface ZhuangbiApi { 20 | 21 | @GET("search") 22 | Observable> search(@Query("q") String id); 23 | 24 | @GET 25 | Call downloadFileWithDynamicUrlSync(@Url String filrUrl); 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/entity/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.entity; 2 | 3 | /** 4 | * Wing_Li 5 | * 2016/4/15. 6 | */ 7 | public class BaseEntity { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/entity/FavoriteEntity.kt: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.entity 2 | 3 | import java.util.* 4 | 5 | data class FavoriteEntity( 6 | var id: String, 7 | var title: String, 8 | var author: String, 9 | var url: String, 10 | var createAt: Date 11 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/entity/SuperGalleryEntity.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.entity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Wing_Li 7 | * 2016/4/14. 8 | */ 9 | public class SuperGalleryEntity extends BaseEntity { 10 | 11 | private boolean end; 12 | private int count; 13 | private int lastid; 14 | private List list; 15 | 16 | public boolean isEnd() { 17 | return end; 18 | } 19 | 20 | public void setEnd(boolean end) { 21 | this.end = end; 22 | } 23 | 24 | public int getCount() { 25 | return count; 26 | } 27 | 28 | public void setCount(int count) { 29 | this.count = count; 30 | } 31 | 32 | public int getLastid() { 33 | return lastid; 34 | } 35 | 36 | public void setLastid(int lastid) { 37 | this.lastid = lastid; 38 | } 39 | 40 | public List getList() { 41 | return list; 42 | } 43 | 44 | public void setList(List list) { 45 | this.list = list; 46 | } 47 | 48 | public static class ListBean extends BaseEntity { 49 | private String id; 50 | private String url; 51 | private String imageid; 52 | private String group_title; 53 | private String tag; 54 | private String label; 55 | private int grpseq; 56 | private String cover_imgurl; 57 | private int cover_height; 58 | private int cover_width; 59 | private int total_count; 60 | private int index; 61 | private String qhimg_url; 62 | private String qhimg_thumb_url; 63 | private int qhimg_width; 64 | private int qhimg_height; 65 | private String dsptime; 66 | 67 | public String getUrl() { 68 | return url; 69 | } 70 | 71 | public void setUrl(String url) { 72 | this.url = url; 73 | } 74 | 75 | public String getId() { 76 | return id; 77 | } 78 | 79 | public void setId(String id) { 80 | this.id = id; 81 | } 82 | 83 | public String getImageid() { 84 | return imageid; 85 | } 86 | 87 | public void setImageid(String imageid) { 88 | this.imageid = imageid; 89 | } 90 | 91 | public String getGroup_title() { 92 | return group_title; 93 | } 94 | 95 | public void setGroup_title(String group_title) { 96 | this.group_title = group_title; 97 | } 98 | 99 | public String getTag() { 100 | return tag; 101 | } 102 | 103 | public void setTag(String tag) { 104 | this.tag = tag; 105 | } 106 | 107 | public String getLabel() { 108 | return label; 109 | } 110 | 111 | public void setLabel(String label) { 112 | this.label = label; 113 | } 114 | 115 | public int getGrpseq() { 116 | return grpseq; 117 | } 118 | 119 | public void setGrpseq(int grpseq) { 120 | this.grpseq = grpseq; 121 | } 122 | 123 | public String getCover_imgurl() { 124 | return cover_imgurl; 125 | } 126 | 127 | public void setCover_imgurl(String cover_imgurl) { 128 | this.cover_imgurl = cover_imgurl; 129 | } 130 | 131 | public int getCover_height() { 132 | return cover_height; 133 | } 134 | 135 | public void setCover_height(int cover_height) { 136 | this.cover_height = cover_height; 137 | } 138 | 139 | public int getCover_width() { 140 | return cover_width; 141 | } 142 | 143 | public void setCover_width(int cover_width) { 144 | this.cover_width = cover_width; 145 | } 146 | 147 | public int getTotal_count() { 148 | return total_count; 149 | } 150 | 151 | public void setTotal_count(int total_count) { 152 | this.total_count = total_count; 153 | } 154 | 155 | public int getIndex() { 156 | return index; 157 | } 158 | 159 | public void setIndex(int index) { 160 | this.index = index; 161 | } 162 | 163 | public String getQhimg_url() { 164 | return qhimg_url; 165 | } 166 | 167 | public void setQhimg_url(String qhimg_url) { 168 | this.qhimg_url = qhimg_url; 169 | } 170 | 171 | public String getQhimg_thumb_url() { 172 | return qhimg_thumb_url; 173 | } 174 | 175 | public void setQhimg_thumb_url(String qhimg_thumb_url) { 176 | this.qhimg_thumb_url = qhimg_thumb_url; 177 | } 178 | 179 | public int getQhimg_width() { 180 | return qhimg_width; 181 | } 182 | 183 | public void setQhimg_width(int qhimg_width) { 184 | this.qhimg_width = qhimg_width; 185 | } 186 | 187 | public int getQhimg_height() { 188 | return qhimg_height; 189 | } 190 | 191 | public void setQhimg_height(int qhimg_height) { 192 | this.qhimg_height = qhimg_height; 193 | } 194 | 195 | public String getDsptime() { 196 | return dsptime; 197 | } 198 | 199 | public void setDsptime(String dsptime) { 200 | this.dsptime = dsptime; 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/entity/SuperMenuEntity.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.entity; 2 | 3 | /** 4 | * Wing_Li 5 | * 2016/4/14. 6 | */ 7 | public class SuperMenuEntity extends BaseEntity { 8 | 9 | private String title; 10 | private String type; 11 | 12 | public SuperMenuEntity(String title, String type) { 13 | this.title = title; 14 | this.type = type; 15 | } 16 | 17 | public String getTitle() { 18 | return title; 19 | } 20 | 21 | public void setTitle(String title) { 22 | this.title = title; 23 | } 24 | 25 | public String getType() { 26 | return type; 27 | } 28 | 29 | public void setType(String type) { 30 | this.type = type; 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/entity/UserInfoEntity.kt: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.entity 2 | 3 | class UserInfoEntity( 4 | var id: String = "", 5 | var email: String = "", 6 | var sessionToken: String = "" 7 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/net/model/UserModel.kt: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.net.model 2 | 3 | import android.content.Context 4 | import android.text.TextUtils 5 | import com.google.gson.Gson 6 | import com.lyl.boon.net.entity.UserInfoEntity 7 | import com.lyl.boon.utils.SPUtils 8 | 9 | class UserModel(var mContext: Context) { 10 | 11 | fun saveUserInfo(user: UserInfoEntity?) { 12 | if (user == null) { 13 | SPUtils.put(mContext, "userInfo", "") 14 | } else { 15 | SPUtils.put(mContext, "userInfo", Gson().toJson(user)) 16 | } 17 | } 18 | 19 | fun getUserInfo(): UserInfoEntity? { 20 | val userJson = SPUtils.get(mContext, "userInfo", "") as? String 21 | if (!TextUtils.isEmpty(userJson)) { 22 | return Gson().fromJson(userJson, UserInfoEntity::class.java) 23 | } 24 | return null 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/ui/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.ui; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.LinearLayout; 9 | import android.widget.TextView; 10 | 11 | import com.lyl.boon.R; 12 | import com.lyl.boon.net.LeanCloudNet; 13 | import com.lyl.boon.net.entity.UserInfoEntity; 14 | import com.lyl.boon.net.model.UserModel; 15 | import com.lyl.boon.ui.account.LoginActivity; 16 | import com.lyl.boon.ui.base.BaseActivity; 17 | import com.tencent.bugly.beta.Beta; 18 | import com.tencent.bugly.crashreport.CrashReport; 19 | 20 | import butterknife.Bind; 21 | import butterknife.ButterKnife; 22 | import butterknife.OnClick; 23 | import cn.leancloud.AVUser; 24 | 25 | /** 26 | * Created by lyl on 2016/12/21. 27 | */ 28 | public class AboutActivity extends BaseActivity { 29 | 30 | @Bind(R.id.user_layout) 31 | LinearLayout userLayout; 32 | @Bind(R.id.user_name) 33 | TextView userName; 34 | @Bind(R.id.btn_login) 35 | Button btnLogin; 36 | @Bind(R.id.check_update) 37 | LinearLayout checkUpdate; 38 | @Bind(R.id.link_text) 39 | LinearLayout linkText; 40 | @Bind(R.id.wing_li) 41 | TextView wingLi; 42 | 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | setContentView(R.layout.activity_about); 48 | ButterKnife.bind(this); 49 | 50 | initActionbar(); 51 | setBackIcon(); 52 | 53 | initView(); 54 | mActionTitle.setText(getString(R.string.about_title)); 55 | } 56 | 57 | private void initView() { 58 | UserInfoEntity userModel = new UserModel(mContext).getUserInfo(); 59 | 60 | if (userModel != null) { 61 | userLayout.setVisibility(View.VISIBLE); 62 | userName.setText(userModel.getEmail()); 63 | btnLogin.setText(R.string.user_exit); 64 | btnLogin.setOnClickListener(new View.OnClickListener() { 65 | @Override 66 | public void onClick(View v) { 67 | userLogout(); 68 | } 69 | }); 70 | 71 | } else { 72 | userLayout.setVisibility(View.GONE); 73 | btnLogin.setText(R.string.user_login); 74 | btnLogin.setOnClickListener(new View.OnClickListener() { 75 | @Override 76 | public void onClick(View v) { 77 | startActivity(new Intent(mContext, LoginActivity.class)); 78 | } 79 | }); 80 | } 81 | } 82 | 83 | @OnClick({R.id.check_update, R.id.link_text, R.id.wing_li}) 84 | public void onClick(View view) { 85 | 86 | switch (view.getId()) { 87 | 88 | case R.id.check_update: 89 | /** 90 | * @param isManual 用户手动点击检查,非用户点击操作请传false 91 | * @param isSilence 是否显示弹窗等交互,[true:没有弹窗和toast] [false:有弹窗或toast] 92 | */ 93 | Beta.checkUpgrade(true, false); 94 | break; 95 | 96 | case R.id.link_text: 97 | openUri("https://github.com/Wing-Li/boon"); 98 | break; 99 | 100 | case R.id.wing_li: 101 | openUri("https://wing-li.github.io/"); 102 | break; 103 | } 104 | } 105 | 106 | private void userLogout() { 107 | LeanCloudNet.INSTANCE.logOut(); 108 | 109 | new UserModel(mContext).saveUserInfo(null); 110 | 111 | Intent intent = new Intent(mContext, MainActivity.class); 112 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); 113 | startActivity(intent); 114 | finish(); 115 | } 116 | 117 | private void openUri(String uri) { 118 | try { 119 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); 120 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 121 | startActivity(intent); 122 | } catch (Exception e) { 123 | CrashReport.postCatchedException(e); 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/ui/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.ui; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.IdRes; 6 | import androidx.fragment.app.Fragment; 7 | import androidx.fragment.app.FragmentTransaction; 8 | 9 | import android.view.KeyEvent; 10 | import android.view.View; 11 | import android.view.Window; 12 | import android.widget.Toast; 13 | 14 | import com.lyl.boon.R; 15 | import com.lyl.boon.ui.base.BaseActivity; 16 | import com.lyl.boon.ui.joke.JokeFragment; 17 | import com.lyl.boon.ui.learn.LearnFragment; 18 | import com.lyl.boon.ui.superboon.SuperBoonFragment; 19 | import com.lyl.boon.ui.wanandroid.WanAndroidFragment; 20 | import com.lyl.boon.ui.young.YoungFragment; 21 | import com.lyl.boon.utils.NetStatusUtil; 22 | import com.roughike.bottombar.BottomBar; 23 | import com.roughike.bottombar.OnTabSelectListener; 24 | 25 | import butterknife.Bind; 26 | import butterknife.ButterKnife; 27 | import me.drakeet.materialdialog.MaterialDialog; 28 | 29 | public class MainActivity extends BaseActivity { 30 | 31 | private LearnFragment learnFragment; 32 | private WanAndroidFragment wanandroidFragment; 33 | private YoungFragment youngFragment; 34 | private JokeFragment jokeFragment; 35 | private SuperBoonFragment superFragment; 36 | 37 | private Fragment oldFragment; 38 | 39 | @Bind(R.id.bottomBar) 40 | BottomBar mBottomBar; 41 | 42 | @Override 43 | protected void onCreate(Bundle savedInstanceState) { 44 | getWindow().requestFeature(Window.FEATURE_ACTION_BAR); 45 | super.onCreate(savedInstanceState); 46 | setContentView(R.layout.activity_main); 47 | 48 | ButterKnife.bind(this); 49 | 50 | initActionbar(); 51 | setAppAbout(); 52 | setFavoriteIcon(); 53 | initBottom(); 54 | initFragmentContent(); 55 | } 56 | 57 | /** 58 | * 设置中间内容页 59 | */ 60 | private void initFragmentContent() { 61 | learnFragment = new LearnFragment(); 62 | getSupportFragmentManager().beginTransaction().add(R.id.fragment_content, learnFragment).commit(); 63 | oldFragment = learnFragment; 64 | } 65 | 66 | /** 67 | * 设置底部按钮 68 | */ 69 | private void initBottom() { 70 | mBottomBar.setOnTabSelectListener(new OnTabSelectListener() { 71 | @Override 72 | public void onTabSelected(@IdRes int tabId) { 73 | 74 | switch (tabId) { 75 | 76 | case R.id.menu_learn: //学习 77 | setActTitle(R.string.menu_learn_msg); 78 | toFragment(learnFragment); 79 | break; 80 | 81 | case R.id.menu_wanandroid: //玩Android 82 | goFragment(0); 83 | break; 84 | 85 | case R.id.menu_joke: //开心 86 | checkNet(1); 87 | break; 88 | 89 | case R.id.menu_young: //美女 90 | checkNet(2); 91 | break; 92 | 93 | case R.id.menu_super: //超级福利 94 | checkNet(3); 95 | break; 96 | 97 | default: 98 | setActTitle(R.string.menu_learn_msg); 99 | toFragment(learnFragment); 100 | break; 101 | } 102 | } 103 | }); 104 | } 105 | 106 | /** 107 | * 检查网络,并跳转 108 | */ 109 | private void checkNet(final int position) { 110 | if (NetStatusUtil.isWifi(MainActivity.this)) { 111 | goFragment(position); 112 | } else { 113 | final MaterialDialog dialog = new MaterialDialog(this); 114 | dialog.setTitle("提示"); 115 | dialog.setMessage("您当前不是WIFI状态,访问会消耗大量的流量,您确定要访问吗?"); 116 | dialog.setPositiveButton("没事儿拼了", new View.OnClickListener() { 117 | @Override 118 | public void onClick(View v) { 119 | goFragment(position); 120 | dialog.dismiss(); 121 | } 122 | }); 123 | dialog.setNegativeButton("还是不看了", new View.OnClickListener() { 124 | @Override 125 | public void onClick(View v) { 126 | dialog.dismiss(); 127 | showToast("(*^__^*) 没事去读书学习吧"); 128 | mBottomBar.selectTabWithId(R.id.menu_wanandroid); 129 | } 130 | }); 131 | 132 | dialog.show(); 133 | } 134 | } 135 | 136 | private void goFragment(int position) { 137 | 138 | switch (position) { 139 | 140 | case 0://玩Android 141 | setActTitle(R.string.menu_wanandroid_msg); 142 | if (wanandroidFragment == null) { 143 | wanandroidFragment = new WanAndroidFragment(); 144 | } 145 | toFragment(wanandroidFragment); 146 | break; 147 | 148 | case 1://开心 149 | setActTitle(R.string.menu_joke_msg); 150 | if (jokeFragment == null) { 151 | jokeFragment = new JokeFragment(); 152 | } 153 | toFragment(jokeFragment); 154 | break; 155 | 156 | case 2: //美女 157 | setActTitle(R.string.menu_young_msg); 158 | if (youngFragment == null) { 159 | youngFragment = new YoungFragment(); 160 | } 161 | toFragment(youngFragment); 162 | break; 163 | 164 | case 3: //超级福利 165 | setActTitle(R.string.menu_super_msg); 166 | if (superFragment == null) { 167 | superFragment = new SuperBoonFragment(); 168 | } 169 | toFragment(superFragment); 170 | break; 171 | 172 | } 173 | } 174 | 175 | /** 176 | * 切换Fragment 177 | * 178 | * @param to 下一个Fragment页面 179 | */ 180 | private void toFragment(Fragment to) { 181 | if (to == oldFragment) return; 182 | 183 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out); 184 | if (!to.isAdded()) { // 先判断是否被add过 185 | transaction.hide(oldFragment).add(R.id.fragment_content, to).commit(); // 隐藏当前的fragment,add下一个到Activity中 186 | } else { 187 | transaction.hide(oldFragment).show(to).commit(); // 隐藏当前的fragment,显示下一个 188 | } 189 | oldFragment = to; 190 | } 191 | 192 | /** 193 | * 设置导航栏的标题 194 | */ 195 | private void setActTitle(int res) { 196 | if (mActionTitle != null) { 197 | mActionTitle.setText(getString(res)); 198 | } 199 | } 200 | 201 | 202 | //*************************** 203 | // 双击返回退出 204 | //*************************** 205 | 206 | private long time = 0; 207 | 208 | @Override 209 | public boolean onKeyDown(int keyCode, KeyEvent event) { 210 | if (keyCode == KeyEvent.KEYCODE_BACK) { 211 | if (System.currentTimeMillis() - time <= 2000) { 212 | finish(); 213 | } else { 214 | time = System.currentTimeMillis(); 215 | Toast.makeText(getApplicationContext(), R.string.exit_app, Toast.LENGTH_SHORT).show(); 216 | } 217 | return true; 218 | } 219 | return super.onKeyDown(keyCode, event); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/ui/MainViewPageAdpater.java: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.ui; 2 | 3 | import androidx.fragment.app.Fragment; 4 | import androidx.fragment.app.FragmentManager; 5 | import androidx.fragment.app.FragmentPagerAdapter; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Wing_Li 11 | * 2016/4/1. 12 | */ 13 | public class MainViewPageAdpater extends FragmentPagerAdapter { 14 | 15 | private List fragments; 16 | private List titles; 17 | 18 | public MainViewPageAdpater(FragmentManager fm, List fragments, List titles) { 19 | super(fm); 20 | this.fragments = fragments; 21 | this.titles = titles; 22 | } 23 | 24 | public MainViewPageAdpater(FragmentManager fm) { 25 | super(fm); 26 | } 27 | 28 | public void setFragments(List fragments, List titles) { 29 | this.fragments = fragments; 30 | this.titles = titles; 31 | notifyDataSetChanged(); 32 | } 33 | 34 | @Override 35 | public Fragment getItem(int position) { 36 | return fragments.get(position); 37 | } 38 | 39 | @Override 40 | public long getItemId(int position) { 41 | return position; 42 | } 43 | 44 | @Override 45 | public CharSequence getPageTitle(int position) { 46 | if (titles != null) { 47 | return titles.get(position); 48 | } 49 | return ""; 50 | } 51 | 52 | @Override 53 | public int getCount() { 54 | return fragments == null ? 0 : fragments.size(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/lyl/boon/ui/account/LoginActivity.kt: -------------------------------------------------------------------------------- 1 | package com.lyl.boon.ui.account 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.text.TextUtils 6 | import android.widget.Button 7 | import android.widget.EditText 8 | import com.lyl.boon.R 9 | import com.lyl.boon.net.LeanCloudCallBack 10 | import com.lyl.boon.net.LeanCloudNet 11 | import com.lyl.boon.net.entity.UserInfoEntity 12 | import com.lyl.boon.net.model.UserModel 13 | import com.lyl.boon.ui.MainActivity 14 | import com.lyl.boon.ui.base.BaseActivity 15 | 16 | class LoginActivity : BaseActivity() { 17 | 18 | override fun onCreate(savedInstanceState: Bundle?) { 19 | super.onCreate(savedInstanceState) 20 | 21 | setContentView(R.layout.activity_login) 22 | 23 | initListener() 24 | } 25 | 26 | private fun initListener() { 27 | findViewById