├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── README_EN.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── libs │ ├── AMap_Location_v2.3.0_20160112.jar │ ├── Bughd_android_sdk_v1.3.7.jar │ └── lite-orm-1.9.2.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── xiecc │ │ └── seeWeather │ │ ├── base │ │ ├── AppBlockCanaryContext.java │ │ ├── BaseActivity.java │ │ ├── BaseApplication.java │ │ ├── BaseFragment.java │ │ ├── BaseViewHolder.java │ │ └── ToolbarActivity.java │ │ ├── common │ │ ├── C.java │ │ ├── IntentKey.java │ │ ├── Irrelevant.java │ │ └── utils │ │ │ ├── CircularAnimUtil.java │ │ │ ├── DensityUtil.java │ │ │ ├── DoubleClickExit.java │ │ │ ├── EnvUtil.java │ │ │ ├── FileSizeUtil.java │ │ │ ├── FileUtil.java │ │ │ ├── RxDrawer.java │ │ │ ├── RxUtil.java │ │ │ ├── SdkUtil.java │ │ │ ├── SharedPreferenceUtil.java │ │ │ ├── StatusBarUtil.java │ │ │ ├── TimeUitl.java │ │ │ ├── ToastUtil.java │ │ │ ├── Util.java │ │ │ ├── VersionUtil.java │ │ │ └── WeChatShareUtil.java │ │ ├── component │ │ ├── AnimRecyclerViewAdapter.java │ │ ├── ApiInterface.java │ │ ├── CrashHandler.java │ │ ├── ImageLoader.java │ │ ├── NotificationHelper.java │ │ ├── OrmLite.java │ │ ├── PLog.java │ │ ├── RetrofitSingleton.java │ │ └── RxBus.java │ │ └── modules │ │ ├── about │ │ ├── domain │ │ │ └── Version.java │ │ └── ui │ │ │ └── AboutActivity.java │ │ ├── city │ │ ├── adapter │ │ │ └── CityAdapter.java │ │ ├── db │ │ │ ├── DBManager.java │ │ │ └── WeatherDB.java │ │ ├── domain │ │ │ ├── City.java │ │ │ └── Province.java │ │ └── ui │ │ │ └── ChoiceCityActivity.java │ │ ├── launch │ │ └── FirstActivity.java │ │ ├── main │ │ ├── adapter │ │ │ ├── CardCityHelper.java │ │ │ ├── HomePagerAdapter.java │ │ │ ├── MultiCityAdapter.java │ │ │ └── WeatherAdapter.java │ │ ├── domain │ │ │ ├── AqiEntity.java │ │ │ ├── BasicEntity.java │ │ │ ├── ChangeCityEvent.java │ │ │ ├── CityEntity.java │ │ │ ├── CityORM.java │ │ │ ├── CondEntity.java │ │ │ ├── DailyForecastEntity.java │ │ │ ├── HourlyForecastEntity.java │ │ │ ├── MultiUpdateEvent.java │ │ │ ├── NowEntity.java │ │ │ ├── SuggestionEntity.java │ │ │ ├── TmpEntity.java │ │ │ ├── Weather.java │ │ │ ├── WeatherAPI.java │ │ │ └── WindEntity.java │ │ ├── listener │ │ │ └── FloatingActionButtonScrollBehavior.java │ │ └── ui │ │ │ ├── DetailCityActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── MainFragment.java │ │ │ ├── MultiCityFragment.java │ │ │ └── SharePresenter.java │ │ ├── service │ │ └── AutoUpdateService.java │ │ └── setting │ │ └── ui │ │ ├── SettingActivity.java │ │ └── SettingFragment.java │ └── res │ ├── anim │ ├── slide_in_right.xml │ ├── zoom_enter.xml │ └── zoom_exit.xml │ ├── drawable-night │ ├── icon_city.xml │ ├── icon_cloth.xml │ ├── icon_flu.xml │ ├── icon_humidity.xml │ ├── icon_sport.xml │ ├── icon_temp.xml │ ├── icon_travel.xml │ └── icon_wind.xml │ ├── drawable │ ├── about_1.xml │ ├── about_2.xml │ ├── about_3.xml │ ├── bug.xml │ ├── code.xml │ ├── erro_404.xml │ ├── github.xml │ ├── home.xml │ ├── ic_add_24dp.xml │ ├── ic_favorite.xml │ ├── ic_icon_wechat.xml │ ├── ic_icon_wechat_line.xml │ ├── ic_location.xml │ ├── ic_menu_about.xml │ ├── ic_menu_city.xml │ ├── ic_menu_set.xml │ ├── ic_multi_cities.xml │ ├── icon_city.xml │ ├── icon_cloth.xml │ ├── icon_flu.xml │ ├── icon_humidity.xml │ ├── icon_sport.xml │ ├── icon_temp.xml │ ├── icon_time.xml │ ├── icon_travel.xml │ ├── icon_wind.xml │ ├── mine.xml │ ├── pay.xml │ ├── progress_bar_states.xml │ ├── share.xml │ ├── side_nav_bar.xml │ └── update.xml │ ├── layout │ ├── activity_about.xml │ ├── activity_choice_city.xml │ ├── activity_detail.xml │ ├── activity_main.xml │ ├── activity_setting.xml │ ├── content_main.xml │ ├── dialog_icon.xml │ ├── dialog_share.xml │ ├── dialog_update.xml │ ├── dialog_weather.xml │ ├── fragment_multicity.xml │ ├── fragment_webview.xml │ ├── item_city.xml │ ├── item_forecast.xml │ ├── item_forecast_line.xml │ ├── item_hour_info.xml │ ├── item_hour_info_line.xml │ ├── item_multi_city.xml │ ├── item_suggestion.xml │ ├── item_temperature.xml │ ├── nav_header_main.xml │ ├── part_about.xml │ ├── part_tab_layout.xml │ ├── part_toolbar.xml │ ├── part_toolbar_indicator.xml │ └── progressbar.xml │ ├── menu │ ├── activity_main_drawer.xml │ └── multi_city_menu.xml │ ├── mipmap-hdpi │ └── first_backpng.png │ ├── mipmap-night │ ├── header_back.png │ └── sun_main.png │ ├── mipmap-xhdpi │ ├── city_beijing_cloudy.png │ ├── city_beijing_rainy.png │ ├── city_beijing_sunny.png │ ├── city_other_cloudy.png │ ├── city_other_rainy.png │ ├── city_other_sunny.png │ ├── city_shanghai_cloudy.png │ ├── city_shanghai_rainy.png │ ├── city_shanghai_sunny.png │ ├── city_suzhou_cloudy.png │ ├── city_suzhou_rain.png │ ├── city_suzhou_sunny.png │ ├── dialog_icon_city.png │ ├── empty.png │ ├── erro.png │ ├── header_back.png │ ├── ic_launcher.png │ ├── iconpoint.png │ ├── none.png │ ├── setting_header.jpg │ ├── sun_main.png │ ├── type_one_cloudy.png │ ├── type_one_cloudytosunny.png │ ├── type_one_fog.png │ ├── type_one_heavy_rain.png │ ├── type_one_light_rain.png │ ├── type_one_snow.png │ ├── type_one_sunny.png │ ├── type_one_thunder_rain.png │ ├── type_one_thunderstorm.png │ ├── type_one_windy.png │ ├── type_two_cloudy.png │ ├── type_two_cloudytosunny.png │ ├── type_two_fog.png │ ├── type_two_hail.png │ ├── type_two_hailrain.png │ ├── type_two_haze.png │ ├── type_two_light_rain.png │ ├── type_two_rain.png │ ├── type_two_snowrain.png │ ├── type_two_sunny.png │ └── type_two_thunderstorm.png │ ├── raw │ └── china_city.db │ ├── transition-v21 │ └── activity_side.xml │ ├── transition │ ├── activity_explode.xml │ ├── activity_fade.xml │ └── activity_side.xml │ ├── values-night │ └── colors.xml │ ├── values-v21 │ ├── strings.xml │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ ├── about.xml │ └── setting.xml ├── build.gradle ├── builddebug ├── changeLog.md ├── clean ├── config.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── day.png ├── night.png └── splash.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.apk 2 | *.ap_ 3 | 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | 9 | # Java class files 10 | *.class 11 | 12 | 13 | # generated files 14 | bin/ 15 | gen/ 16 | 17 | 18 | # Local configuration file (sdk path, etc) 19 | local.properties 20 | 21 | 22 | # Windows thumbnail db 23 | Thumbs.db 24 | 25 | 26 | # OSX files 27 | .DS_Store 28 | 29 | 30 | # Eclipse project files 31 | .classpath 32 | .project 33 | 34 | 35 | # Android Studio 36 | .idea 37 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 38 | .gradle 39 | build/ 40 | 41 | 42 | # Signing files 43 | .signing/ 44 | 45 | # iml files 46 | *.iml 47 | projectFilesBackup/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | 4 | env: 5 | global: 6 | - ANDROID_TARGET=android-25 7 | - ANDROID_BUILD_TOOLS_VERSION=26.0.1 8 | - ANDROID_ABI=armeabi-v7a 9 | 10 | android: 11 | components: 12 | - tools 13 | - build-tools-$ANDROID_BUILD_TOOLS_VERSION 14 | - android-22 15 | - $ANDROID_TARGET 16 | - sys-img-armeabi-v7a-android-22 17 | - extra-android-m2repository 18 | - extra-android-support 19 | - extra 20 | licenses: 21 | - android-sdk-license-.+ 22 | 23 | before_install: 24 | - echo yes | android update sdk --all --filter build-tools-$ANDROID_BUILD_TOOLS_VERSION --no-ui --force 25 | 26 | before_script: 27 | - chmod +x gradlew 28 | - echo no | android create avd --force -n test -t android-22 --abi $ANDROID_ABI 29 | - emulator -avd test -no-window & 30 | 31 | script: 32 | - android-wait-for-emulator 33 | - adb shell input keyevent 82 & 34 | 35 | notifications: 36 | email: 37 | - Hugo3641@gmail.com -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'me.tatarka.retrolambda' 3 | 4 | android { 5 | def app = rootProject.ext.android 6 | 7 | compileSdkVersion app.compileSdkVersion 8 | buildToolsVersion app.buildToolsVersion 9 | 10 | defaultConfig { 11 | applicationId app.applicationId 12 | minSdkVersion app.minSdkVersion 13 | targetSdkVersion app.targetSdkVersion 14 | versionCode app.versionCode 15 | versionName app.versionName 16 | resConfigs app.resConfigs 17 | 18 | buildConfigField "String", "$rootProject.ext.weather.name", "\"$rootProject.ext.weather.value\"" 19 | buildConfigField "String", "$rootProject.ext.fir.name", "\"$rootProject.ext.fir.value\"" 20 | } 21 | 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | shrinkResources false 27 | } 28 | debug { 29 | debuggable true 30 | } 31 | } 32 | 33 | compileOptions { 34 | //使用JAVA8语法解析 35 | sourceCompatibility JavaVersion.VERSION_1_8 36 | targetCompatibility JavaVersion.VERSION_1_8 37 | } 38 | 39 | lintOptions { 40 | disable 'InvalidPackage', 'MissingTranslation', 'ExtraTranslation' 41 | } 42 | 43 | dexOptions { 44 | javaMaxHeapSize "4g" 45 | } 46 | 47 | packagingOptions { 48 | 49 | exclude 'META-INF/services/javax.annotation.processing.Processor' 50 | } 51 | } 52 | 53 | dependencies { 54 | compile fileTree(include: ['*.jar'], dir: 'libs') 55 | // 默认 UI 56 | compile 'com.android.support:appcompat-v7:25.3.1' 57 | compile 'com.android.support:design:25.3.1' 58 | compile 'com.android.support:cardview-v7:25.3.1' 59 | compile 'com.android.support:support-v4:25.3.1' 60 | // Rx 61 | compile 'io.reactivex.rxjava2:rxjava:2.1.0' 62 | compile 'io.reactivex.rxjava2:rxandroid:2.0.1' 63 | compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4' 64 | compile 'com.trello.rxlifecycle2:rxlifecycle:2.0.1' 65 | compile 'com.trello.rxlifecycle2:rxlifecycle-android:2.0.1' 66 | compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.0.1' 67 | // network 68 | compile 'com.google.code.gson:gson:2.8.0' 69 | compile 'com.squareup.retrofit2:retrofit:2.2.0' 70 | compile 'com.squareup.retrofit2:converter-gson:2.2.0' 71 | compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' 72 | compile 'com.squareup.okhttp3:okhttp:3.7.0' 73 | compile 'com.github.bumptech.glide:glide:3.7.0' 74 | 75 | compile 'com.jakewharton:butterknife:8.5.1' 76 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' 77 | 78 | // assist 79 | debugCompile 'com.github.markzhai:blockcanary-android:1.5.0' 80 | releaseCompile 'com.github.markzhai:blockcanary-no-op:1.5.0' 81 | debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1' 82 | releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1' 83 | 84 | compile 'com.github.xcc3641:watcher:1.0' 85 | compile 'com.facebook.stetho:stetho:1.5.0' 86 | compile 'com.facebook.stetho:stetho-okhttp3:1.5.0' 87 | 88 | //share 89 | compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:1.1.6' 90 | } 91 | 92 | -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "1049478372464", 4 | "firebase_url": "https://project-4327957269886013363.firebaseio.com", 5 | "project_id": "project-4327957269886013363", 6 | "storage_bucket": "project-4327957269886013363.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:1049478372464:android:4efc94ee100efa12", 12 | "android_client_info": { 13 | "package_name": "com.xiecc.seeWeather" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "1049478372464-9sh9372m5q8c2vkj0lf6g7ff58364v81.apps.googleusercontent.com", 19 | "client_type": 3 20 | } 21 | ], 22 | "api_key": [ 23 | { 24 | "current_key": "AIzaSyCvXEeNa0qHlMMFWDbCq3xc02pwM3d4IZY" 25 | } 26 | ], 27 | "services": { 28 | "analytics_service": { 29 | "status": 1 30 | }, 31 | "appinvite_service": { 32 | "status": 1, 33 | "other_platform_oauth_client": [] 34 | }, 35 | "ads_service": { 36 | "status": 2 37 | } 38 | } 39 | } 40 | ], 41 | "configuration_version": "1" 42 | } -------------------------------------------------------------------------------- /app/libs/AMap_Location_v2.3.0_20160112.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/libs/AMap_Location_v2.3.0_20160112.jar -------------------------------------------------------------------------------- /app/libs/Bughd_android_sdk_v1.3.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/libs/Bughd_android_sdk_v1.3.7.jar -------------------------------------------------------------------------------- /app/libs/lite-orm-1.9.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/libs/lite-orm-1.9.2.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\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/java/com/xiecc/seeWeather/base/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.base; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.app.AppCompatDelegate; 7 | import butterknife.ButterKnife; 8 | import com.trello.rxlifecycle2.components.support.RxAppCompatActivity; 9 | 10 | public abstract class BaseActivity extends RxAppCompatActivity { 11 | private static String TAG = BaseActivity.class.getSimpleName(); 12 | 13 | @Override 14 | protected void onCreate(@Nullable Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(layoutId()); 17 | ButterKnife.bind(this); 18 | } 19 | 20 | protected abstract int layoutId(); 21 | 22 | @Override 23 | protected void onStop() { 24 | super.onStop(); 25 | } 26 | 27 | @Override 28 | protected void onDestroy() { 29 | super.onDestroy(); 30 | } 31 | 32 | public static void setDayTheme(AppCompatActivity activity) { 33 | AppCompatDelegate.setDefaultNightMode( 34 | AppCompatDelegate.MODE_NIGHT_NO); 35 | activity.getDelegate().setLocalNightMode( 36 | AppCompatDelegate.MODE_NIGHT_NO); 37 | // 调用 recreate() 使设置生效 38 | activity.recreate(); 39 | } 40 | 41 | public static void setNightTheme(AppCompatActivity activity) { 42 | AppCompatDelegate.setDefaultNightMode( 43 | AppCompatDelegate.MODE_NIGHT_YES); 44 | activity.getDelegate().setLocalNightMode( 45 | AppCompatDelegate.MODE_NIGHT_YES); 46 | // 调用 recreate() 使设置生效 47 | activity.recreate(); 48 | } 49 | 50 | public void setTheme(AppCompatActivity activity) { 51 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO); 52 | activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_AUTO); 53 | activity.recreate(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/base/BaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.base; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.support.v7.app.AppCompatDelegate; 6 | import com.facebook.stetho.Stetho; 7 | import com.github.moduth.blockcanary.BlockCanary; 8 | import com.hugo.watcher.Watcher; 9 | import com.squareup.leakcanary.LeakCanary; 10 | import com.xiecc.seeWeather.BuildConfig; 11 | import com.xiecc.seeWeather.component.CrashHandler; 12 | import com.xiecc.seeWeather.component.PLog; 13 | import im.fir.sdk.FIR; 14 | import io.reactivex.plugins.RxJavaPlugins; 15 | 16 | public class BaseApplication extends Application { 17 | 18 | private static String sCacheDir; 19 | private static Context sAppContext; 20 | 21 | // TODO: 16/8/1 这里的夜间模式 UI 有些没有适配好 暂时放弃夜间模式 22 | static { 23 | AppCompatDelegate.setDefaultNightMode( 24 | AppCompatDelegate.MODE_NIGHT_NO); 25 | } 26 | 27 | @Override 28 | public void onCreate() { 29 | super.onCreate(); 30 | sAppContext = getApplicationContext(); 31 | CrashHandler.init(new CrashHandler(getApplicationContext())); 32 | if (!BuildConfig.DEBUG) { 33 | FIR.init(this); 34 | } else { 35 | Watcher.getInstance().start(this); 36 | Stetho.initializeWithDefaults(this); 37 | } 38 | BlockCanary.install(this, new AppBlockCanaryContext()).start(); 39 | LeakCanary.install(this); 40 | RxJavaPlugins.setErrorHandler(throwable -> { 41 | if (throwable != null) { 42 | PLog.e(throwable.toString()); 43 | } else { 44 | PLog.e("call onError but exception is null"); 45 | } 46 | }); 47 | /* 48 | * 如果存在SD卡则将缓存写入SD卡,否则写入手机内存 49 | */ 50 | if (getApplicationContext().getExternalCacheDir() != null && ExistSDCard()) { 51 | sCacheDir = getApplicationContext().getExternalCacheDir().toString(); 52 | } else { 53 | sCacheDir = getApplicationContext().getCacheDir().toString(); 54 | } 55 | } 56 | 57 | private boolean ExistSDCard() { 58 | return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); 59 | } 60 | 61 | public static Context getAppContext() { 62 | return sAppContext; 63 | } 64 | 65 | public static String getAppCacheDir() { 66 | return sCacheDir; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/base/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.base; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.ActionBar; 6 | import android.support.v7.app.AppCompatActivity; 7 | import com.trello.rxlifecycle2.components.support.RxFragment; 8 | 9 | /** 10 | * Created by HugoXie on 16/7/9. 11 | * 12 | * Email: Hugo3641@gamil.com 13 | * GitHub: https://github.com/xcc3641 14 | * Info: 15 | */ 16 | public abstract class BaseFragment extends RxFragment { 17 | 18 | protected boolean mIsCreateView = false; 19 | 20 | @Override 21 | public void setUserVisibleHint(boolean isVisibleToUser) { 22 | super.setUserVisibleHint(isVisibleToUser); 23 | if (isVisibleToUser && mIsCreateView) { 24 | lazyLoad(); 25 | } 26 | } 27 | 28 | /** 29 | * 加载数据操作,在视图创建之前初始化 30 | */ 31 | protected abstract void lazyLoad(); 32 | 33 | @Override 34 | public void onActivityCreated(@Nullable Bundle savedInstanceState) { 35 | super.onActivityCreated(savedInstanceState); 36 | if (getUserVisibleHint()) { 37 | lazyLoad(); 38 | } 39 | } 40 | 41 | protected void safeSetTitle(String title) { 42 | ActionBar appBarLayout = ((AppCompatActivity) getActivity()).getSupportActionBar(); 43 | if (appBarLayout != null) { 44 | appBarLayout.setTitle(title); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/base/BaseViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.base; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import butterknife.ButterKnife; 6 | 7 | public abstract class BaseViewHolder extends RecyclerView.ViewHolder { 8 | 9 | public BaseViewHolder(View itemView) { 10 | super(itemView); 11 | ButterKnife.bind(this, itemView); 12 | } 13 | 14 | protected abstract void bind(T t); 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/base/ToolbarActivity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.base; 2 | 3 | import android.os.Build; 4 | import android.os.Bundle; 5 | import android.support.design.widget.AppBarLayout; 6 | import android.support.v7.app.ActionBar; 7 | import android.support.v7.widget.Toolbar; 8 | import android.view.MenuItem; 9 | import android.view.animation.DecelerateInterpolator; 10 | import com.xiecc.seeWeather.R; 11 | 12 | /** 13 | * Created by HugoXie on 16/6/24. 14 | * 15 | * Email: Hugo3641@gamil.com 16 | * GitHub: https://github.com/xcc3641 17 | * Info: 适配所有 toolbar 的 activity 灵感来源 MeiZhi 18 | */ 19 | public abstract class ToolbarActivity extends BaseActivity { 20 | 21 | public void onToolbarClick() { 22 | } 23 | 24 | protected AppBarLayout mAppBar; 25 | protected Toolbar mToolbar; 26 | protected boolean mIsHidden = false; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | mAppBar = (AppBarLayout) findViewById(R.id.appbar_layout); 32 | mToolbar = (Toolbar) findViewById(R.id.toolbar); 33 | if (mToolbar == null || mAppBar == null) { 34 | throw new IllegalStateException( 35 | "The subclass of ToolbarActivity must contain a toolbar."); 36 | } 37 | mToolbar.setOnClickListener(v -> onToolbarClick()); 38 | setSupportActionBar(mToolbar); 39 | if (canBack()) { 40 | ActionBar actionBar = getSupportActionBar(); 41 | if (actionBar != null) actionBar.setDisplayHomeAsUpEnabled(true); 42 | } 43 | if (Build.VERSION.SDK_INT >= 21) { 44 | mAppBar.setElevation(10.6f); 45 | } 46 | } 47 | 48 | public boolean canBack() { 49 | return false; 50 | } 51 | 52 | protected void setAppBarAlpha(float alpha) { 53 | mAppBar.setAlpha(alpha); 54 | } 55 | 56 | public Toolbar getToolbar() { 57 | return mToolbar; 58 | } 59 | 60 | @Override 61 | public boolean onOptionsItemSelected(MenuItem item) { 62 | if (item.getItemId() == android.R.id.home) { 63 | onBackPressed(); 64 | return true; 65 | } else { 66 | return super.onOptionsItemSelected(item); 67 | } 68 | } 69 | 70 | protected void hideOrShowToolbar() { 71 | mAppBar.animate() 72 | .translationY(mIsHidden ? 0 : -mAppBar.getHeight()) 73 | .setInterpolator(new DecelerateInterpolator(2)) 74 | .start(); 75 | mIsHidden = !mIsHidden; 76 | } 77 | 78 | protected void safeSetTitle(String title) { 79 | ActionBar appBarLayout = getSupportActionBar(); 80 | if (appBarLayout != null) { 81 | appBarLayout.setTitle(title); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/C.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common; 2 | 3 | import com.xiecc.seeWeather.BuildConfig; 4 | import com.xiecc.seeWeather.base.BaseApplication; 5 | import java.io.File; 6 | 7 | /** 8 | * Created by HugoXie on 16/5/23. 9 | * 10 | * Email: Hugo3641@gamil.com 11 | * GitHub: https://github.com/xcc3641 12 | * Info: 常量类 13 | */ 14 | public class C { 15 | 16 | public static final String API_TOKEN = BuildConfig.FirToken; 17 | public static final String KEY = BuildConfig.WeatherKey;// 和风天气 key 18 | 19 | public static final String MULTI_CHECK = "multi_check"; 20 | 21 | public static final String ORM_NAME = "cities.db"; 22 | 23 | public static final String UNKNOWN_CITY = "unknown city"; 24 | 25 | public static final String NET_CACHE = BaseApplication.getAppCacheDir() + File.separator + "NetCache"; 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/IntentKey.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common; 2 | 3 | /** 4 | * Created by HugoXie on 2017/5/10. 5 | * 6 | * Email: Hugo3641@gmail.com 7 | * GitHub: https://github.com/xcc3641 8 | * Info: 9 | */ 10 | 11 | public class IntentKey { 12 | 13 | public static final String WEATHER = "weather"; 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/Irrelevant.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common; 2 | 3 | public enum Irrelevant { 4 | INSTANCE 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/DensityUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.content.res.Resources; 4 | import android.support.annotation.DimenRes; 5 | import com.xiecc.seeWeather.base.BaseApplication; 6 | 7 | public class DensityUtil { 8 | 9 | private static Resources sRes = Resources.getSystem(); 10 | private static int sDensityDpi = sRes.getDisplayMetrics().densityDpi; 11 | private static float sScaledDensity = sRes.getDisplayMetrics().scaledDensity; 12 | 13 | public static int dp2px(float value) { 14 | final float scale = sDensityDpi; 15 | return (int) (value * (scale / 160) + 0.5f); 16 | } 17 | 18 | public static int px2dp(float value) { 19 | final float scale = sDensityDpi; 20 | return (int) ((value * 160) / scale + 0.5f); 21 | } 22 | 23 | public static int sp2px(float value) { 24 | float spValue = value * sScaledDensity; 25 | return (int) (spValue + 0.5f); 26 | } 27 | 28 | public static int px2sp(float value) { 29 | final float scale = sScaledDensity; 30 | return (int) (value / scale + 0.5f); 31 | } 32 | 33 | public static int dimenPixelSize(@DimenRes int id) { 34 | return BaseApplication.getAppContext().getResources().getDimensionPixelSize(id); 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/DoubleClickExit.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | /** 4 | * Created by HugoXie on 16/6/25. 5 | * 6 | * Email: Hugo3641@gamil.com 7 | * GitHub: https://github.com/xcc3641 8 | * Info: 9 | */ 10 | public class DoubleClickExit { 11 | /** 12 | * 双击退出检测, 阈值 1000ms 13 | */ 14 | public static long mLastClick = 0L; 15 | private static final int THRESHOLD = 2000;// 1000ms 16 | 17 | public static boolean check() { 18 | long now = System.currentTimeMillis(); 19 | boolean b = now - mLastClick < THRESHOLD; 20 | mLastClick = now; 21 | return b; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/EnvUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.content.Context; 4 | import android.util.TypedValue; 5 | import com.xiecc.seeWeather.base.BaseApplication; 6 | 7 | public class EnvUtil { 8 | 9 | private static int sStatusBarHeight; 10 | 11 | public static int getActionBarSize(Context context) { 12 | TypedValue tv = new TypedValue(); 13 | if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { 14 | return TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics()); 15 | } 16 | return DensityUtil.dp2px(44); 17 | } 18 | 19 | public static int getStatusBarHeight() { 20 | if (sStatusBarHeight == 0) { 21 | int resourceId = 22 | BaseApplication.getAppContext().getResources().getIdentifier("status_bar_height", "dimen", "android"); 23 | if (resourceId > 0) { 24 | sStatusBarHeight = BaseApplication.getAppContext().getResources().getDimensionPixelSize(resourceId); 25 | } 26 | } 27 | return sStatusBarHeight; 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/FileUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * Created by HugoXie on 16/7/26. 7 | * 8 | * Email: Hugo3641@gamil.com 9 | * GitHub: https://github.com/xcc3641 10 | * Info: 11 | */ 12 | public class FileUtil { 13 | 14 | public static boolean delete(File file) { 15 | if (file.isFile()) { 16 | return file.delete(); 17 | } 18 | 19 | if (file.isDirectory()) { 20 | File[] childFiles = file.listFiles(); 21 | if (childFiles == null || childFiles.length == 0) { 22 | return file.delete(); 23 | } 24 | 25 | for (File childFile : childFiles) { 26 | delete(childFile); 27 | } 28 | return file.delete(); 29 | } 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/RxDrawer.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.support.v4.view.GravityCompat; 4 | import android.support.v4.widget.DrawerLayout; 5 | import android.support.v4.widget.DrawerLayout.DrawerListener; 6 | import android.view.View; 7 | import com.xiecc.seeWeather.common.Irrelevant; 8 | import io.reactivex.Observable; 9 | 10 | /** 11 | * Created by HugoXie on 16/6/25. 12 | * 13 | * Email: Hugo3641@gamil.com 14 | * GitHub: https://github.com/xcc3641 15 | * Info: 16 | */ 17 | public class RxDrawer { 18 | 19 | private static final float OFFSET_THRESHOLD = 0.03f; 20 | 21 | public static Observable close(final DrawerLayout drawer) { 22 | return Observable.create(emitter -> { 23 | drawer.closeDrawer(GravityCompat.START); 24 | DrawerListener listener = new DrawerLayout.SimpleDrawerListener() { 25 | @Override 26 | public void onDrawerSlide(View drawerView, float slideOffset) { 27 | if (slideOffset < OFFSET_THRESHOLD) { 28 | emitter.onNext(Irrelevant.INSTANCE); 29 | emitter.onComplete(); 30 | drawer.removeDrawerListener(this); 31 | } 32 | } 33 | }; 34 | drawer.addDrawerListener(listener); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/RxUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import com.trello.rxlifecycle2.android.ActivityEvent; 4 | import com.trello.rxlifecycle2.android.FragmentEvent; 5 | import com.trello.rxlifecycle2.components.support.RxAppCompatActivity; 6 | import com.trello.rxlifecycle2.components.support.RxFragment; 7 | import io.reactivex.FlowableTransformer; 8 | import io.reactivex.ObservableTransformer; 9 | import io.reactivex.Scheduler; 10 | import io.reactivex.android.schedulers.AndroidSchedulers; 11 | import io.reactivex.schedulers.Schedulers; 12 | 13 | /** 14 | * Created by HugoXie on 16/5/19. 15 | * 16 | * Email: Hugo3641@gamil.com 17 | * GitHub: https://github.com/xcc3641 18 | * Info: 封装 Rx 的一些方法 19 | */ 20 | public class RxUtil { 21 | 22 | private static ObservableTransformer schedulerTransformer(Scheduler scheduler) { 23 | return observable -> 24 | observable 25 | .subscribeOn(scheduler) 26 | .observeOn(AndroidSchedulers.mainThread(), true); 27 | } 28 | 29 | public static ObservableTransformer io() { 30 | return schedulerTransformer(Schedulers.io()); 31 | } 32 | 33 | private static FlowableTransformer schedulerTransformerF(Scheduler scheduler) { 34 | return flowable -> 35 | flowable 36 | .subscribeOn(scheduler) 37 | .observeOn(AndroidSchedulers.mainThread(), true); 38 | } 39 | 40 | public static FlowableTransformer ioF() { 41 | return schedulerTransformerF(Schedulers.io()); 42 | } 43 | 44 | public static ObservableTransformer activityLifecycle(RxAppCompatActivity activity) { 45 | return observable -> 46 | observable.compose(activity.bindUntilEvent(ActivityEvent.DESTROY)); 47 | } 48 | 49 | public static ObservableTransformer fragmentLifecycle(RxFragment fragment) { 50 | return observable -> 51 | observable.compose(fragment.bindUntilEvent(FragmentEvent.DESTROY)); 52 | } 53 | 54 | public static FlowableTransformer activityLifecycleF(RxAppCompatActivity activity) { 55 | return flowable -> 56 | flowable.compose(activity.bindUntilEvent(ActivityEvent.DESTROY)); 57 | } 58 | 59 | public static FlowableTransformer fragmentLifecycleF(RxFragment fragment) { 60 | return flowable -> 61 | flowable.compose(fragment.bindUntilEvent(FragmentEvent.DESTROY)); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/SdkUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.os.Build; 4 | 5 | public class SdkUtil { 6 | 7 | public static boolean sdkVersionGe(int version) { 8 | return Build.VERSION.SDK_INT >= version; 9 | } 10 | 11 | public static boolean sdkVersionEq(int version) { 12 | return Build.VERSION.SDK_INT == version; 13 | } 14 | 15 | public static boolean sdkVersionLt(int version) { 16 | return Build.VERSION.SDK_INT < version; 17 | } 18 | 19 | public static boolean sdkVersionGe19() { 20 | return sdkVersionGe(19); 21 | } 22 | 23 | public static boolean sdkVersionGe21() { 24 | return sdkVersionGe(21); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/StatusBarUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.support.annotation.NonNull; 7 | import android.support.v7.widget.Toolbar; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.view.WindowManager; 11 | 12 | public class StatusBarUtil { 13 | 14 | public static void setImmersiveStatusBar(@NonNull Activity activity) { 15 | if (SdkUtil.sdkVersionGe21()) { 16 | activity.getWindow().setStatusBarColor(Color.TRANSPARENT); 17 | } 18 | if (SdkUtil.sdkVersionEq(19)) { 19 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, 20 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 21 | } 22 | activity.getWindow() 23 | .getDecorView() 24 | .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 25 | } 26 | 27 | public static void setImmersiveStatusBarToolbar(@NonNull Toolbar toolbar, Context context) { 28 | ViewGroup.MarginLayoutParams toolLayoutParams = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); 29 | toolLayoutParams.height = EnvUtil.getStatusBarHeight() + EnvUtil.getActionBarSize(context); 30 | toolbar.setLayoutParams(toolLayoutParams); 31 | toolbar.setPadding(0, EnvUtil.getStatusBarHeight(), 0, 0); 32 | toolbar.requestLayout(); 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/TimeUitl.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.annotation.SuppressLint; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Calendar; 6 | import java.util.Date; 7 | 8 | public class TimeUitl { 9 | 10 | /** 11 | * yyyy-MM-dd HH:mm:ss 12 | */ 13 | @SuppressLint("SimpleDateFormat") 14 | public static String getNowYMDHMSTime() { 15 | SimpleDateFormat mDateFormat = new SimpleDateFormat( 16 | "yyyy-MM-dd HH:mm:ss"); 17 | return mDateFormat.format(new Date()); 18 | } 19 | 20 | /** 21 | * MM-dd HH:mm:ss 22 | */ 23 | @SuppressLint("SimpleDateFormat") 24 | public static String getNowMDHMSTime() { 25 | SimpleDateFormat mDateFormat = new SimpleDateFormat( 26 | "MM-dd HH:mm:ss"); 27 | return mDateFormat.format(new Date()); 28 | } 29 | 30 | /** 31 | * MM-dd 32 | */ 33 | @SuppressLint("SimpleDateFormat") 34 | public static String getNowYMD() { 35 | 36 | SimpleDateFormat mDateFormat = new SimpleDateFormat( 37 | "yyyy-MM-dd"); 38 | return mDateFormat.format(new Date()); 39 | } 40 | 41 | /** 42 | * yyyy-MM-dd 43 | */ 44 | @SuppressLint("SimpleDateFormat") 45 | public static String getYMD(Date date) { 46 | 47 | SimpleDateFormat mDateFormat = new SimpleDateFormat( 48 | "yyyy-MM-dd"); 49 | return mDateFormat.format(date); 50 | } 51 | 52 | @SuppressLint("SimpleDateFormat") 53 | public static String getMD(Date date) { 54 | 55 | SimpleDateFormat mDateFormat = new SimpleDateFormat( 56 | "MM-dd"); 57 | return mDateFormat.format(date); 58 | } 59 | 60 | /** 61 | * 判断当前日期是星期几 62 | * 63 | * @param pTime 修要判断的时间 64 | * @return dayForWeek 判断结果 65 | * @Exception 发生异常 66 | */ 67 | public static String dayForWeek(String pTime) throws Exception { 68 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 69 | Calendar c = Calendar.getInstance(); 70 | c.setTime(format.parse(pTime)); 71 | int dayForWeek; 72 | String week = ""; 73 | dayForWeek = c.get(Calendar.DAY_OF_WEEK); 74 | switch (dayForWeek) { 75 | case 1: 76 | week = "星期日"; 77 | break; 78 | case 2: 79 | week = "星期一"; 80 | break; 81 | case 3: 82 | week = "星期二"; 83 | break; 84 | case 4: 85 | week = "星期三"; 86 | break; 87 | case 5: 88 | week = "星期四"; 89 | break; 90 | case 6: 91 | week = "星期五"; 92 | break; 93 | case 7: 94 | week = "星期六"; 95 | break; 96 | } 97 | return week; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/ToastUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.widget.Toast; 4 | import com.xiecc.seeWeather.base.BaseApplication; 5 | 6 | /** 7 | * Created by HugoXie on 16/5/23. 8 | * 9 | * Email: Hugo3641@gamil.com 10 | * GitHub: https://github.com/xcc3641 11 | * Info: 12 | */ 13 | public class ToastUtil { 14 | 15 | public static void showShort(String msg) { 16 | Toast.makeText(BaseApplication.getAppContext(), msg, Toast.LENGTH_SHORT).show(); 17 | } 18 | 19 | public static void showLong(String msg) { 20 | Toast.makeText(BaseApplication.getAppContext(), msg, Toast.LENGTH_LONG).show(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/common/utils/WeChatShareUtil.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.common.utils; 2 | 3 | import android.content.ComponentName; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | /** 8 | * Created by HugoXie on 2017/5/21. 9 | * 10 | * Email: Hugo3641@gmail.com 11 | * GitHub: https://github.com/xcc3641 12 | * Info: 临时微信分享工具 13 | */ 14 | @Deprecated 15 | public class WeChatShareUtil { 16 | 17 | public static void toFriends(Context context, String text) { 18 | Intent intent = new Intent(); 19 | ComponentName comp = new ComponentName("com.tencent.mm", 20 | "com.tencent.mm.ui.tools.ShareImgUI"); 21 | intent.setComponent(comp); 22 | intent.setAction("android.intent.action.SEND"); 23 | intent.putExtra(Intent.EXTRA_TEXT, text); 24 | context.startActivity(intent); 25 | } 26 | 27 | public static void toTimeLine(Context context, String text) { 28 | Intent intent = new Intent(); 29 | ComponentName comp = new ComponentName("com.tencent.mm", 30 | "com.tencent.mm.ui.tools.ShareToTimeLineUI"); 31 | intent.setComponent(comp); 32 | intent.setAction("android.intent.action.SEND"); 33 | intent.putExtra(Intent.EXTRA_TEXT, text); 34 | context.startActivity(intent); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/component/AnimRecyclerViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.component; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.view.animation.Animation; 8 | import android.view.animation.AnimationUtils; 9 | import com.xiecc.seeWeather.R; 10 | 11 | /** 12 | * Created by bruce on 2016-04-30. 13 | * Project: newsnow 14 | */ 15 | 16 | /** 17 | * Thanks for drakeet/Meizhi 18 | *

19 | * https://github.com/drakeet/Meizhi/blob/master/app%2Fsrc%2Fmain%2Fjava%2Fme%2Fdrakeet%2Fmeizhi%2Fui%2Fadapter%2FAnimRecyclerViewAdapter.java 20 | */ 21 | public class AnimRecyclerViewAdapter 22 | extends RecyclerView.Adapter { 23 | 24 | private static final int DELAY = 138; 25 | private int mLastPosition = -1; 26 | 27 | 28 | @Override 29 | public T onCreateViewHolder(ViewGroup parent, int viewType) { 30 | return null; 31 | } 32 | 33 | 34 | @Override 35 | public void onBindViewHolder(T holder, int position) { 36 | } 37 | 38 | 39 | @Override 40 | public int getItemCount() { 41 | return 0; 42 | } 43 | 44 | 45 | public void showItemAnim(final View view, final int position) { 46 | Context context = view.getContext(); 47 | if (position > mLastPosition) { 48 | view.setAlpha(0); 49 | view.postDelayed(() -> { 50 | Animation animation = AnimationUtils.loadAnimation(context, 51 | R.anim.slide_in_right); 52 | animation.setAnimationListener(new Animation.AnimationListener() { 53 | @Override 54 | public void onAnimationStart(Animation animation) { 55 | view.setAlpha(1); 56 | } 57 | 58 | 59 | @Override 60 | public void onAnimationEnd(Animation animation) { 61 | } 62 | 63 | 64 | @Override 65 | public void onAnimationRepeat(Animation animation) { 66 | } 67 | }); 68 | view.startAnimation(animation); 69 | }, DELAY * position); 70 | mLastPosition = position; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/component/ApiInterface.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.component; 2 | 3 | import com.xiecc.seeWeather.modules.about.domain.Version; 4 | import com.xiecc.seeWeather.modules.main.domain.WeatherAPI; 5 | import io.reactivex.Flowable; 6 | import io.reactivex.Observable; 7 | import retrofit2.http.GET; 8 | import retrofit2.http.Query; 9 | 10 | public interface ApiInterface { 11 | 12 | String HOST = "https://free-api.heweather.com/v5/"; 13 | 14 | @GET("weather") 15 | Observable mWeatherAPI(@Query("city") String city, @Query("key") String key); 16 | 17 | @GET("weather") 18 | Flowable mWeatherAPIF(@Query("city") String city, @Query("key") String key); 19 | 20 | //而且在Retrofit 2.0中我们还可以在@Url里面定义完整的URL:这种情况下Base URL会被忽略。 21 | @GET("http://api.fir.im/apps/latest/5630e5f1f2fc425c52000006") 22 | Observable mVersionAPI(@Query("api_token") String api_token); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/component/CrashHandler.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.component; 2 | 3 | import android.content.Context; 4 | import com.xiecc.seeWeather.common.utils.SharedPreferenceUtil; 5 | import com.xiecc.seeWeather.common.utils.VersionUtil; 6 | import java.io.PrintWriter; 7 | import java.io.StringWriter; 8 | import java.io.Writer; 9 | 10 | /** 11 | * Created by zk on 2015/12/24. 12 | * 捕获程序崩溃信息 13 | */ 14 | public class CrashHandler implements Thread.UncaughtExceptionHandler { 15 | 16 | private static Thread.UncaughtExceptionHandler mDefaultHandler = null; 17 | 18 | private Context mContext = null; 19 | 20 | private final String TAG = CrashHandler.class.getSimpleName(); 21 | 22 | public CrashHandler(Context context) { 23 | this.mContext = context; 24 | } 25 | 26 | /** 27 | * 初始化,设置该CrashHandler为程序的默认处理器 28 | */ 29 | public static void init(CrashHandler crashHandler) { 30 | mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); 31 | Thread.setDefaultUncaughtExceptionHandler(crashHandler); 32 | } 33 | 34 | @Override 35 | public void uncaughtException(Thread thread, Throwable ex) { 36 | System.out.println(ex.toString()); 37 | PLog.e(TAG, ex.toString()); 38 | PLog.e(TAG, collectCrashDeviceInfo()); 39 | PLog.e(TAG, getCrashInfo(ex)); 40 | 41 | // T崩溃后自动初始化数据 42 | SharedPreferenceUtil.getInstance().setCityName("北京"); 43 | OrmLite.getInstance().deleteDatabase(); 44 | // 调用系统错误机制 45 | mDefaultHandler.uncaughtException(thread, ex); 46 | } 47 | 48 | /** 49 | * 得到程序崩溃的详细信息 50 | */ 51 | private String getCrashInfo(Throwable ex) { 52 | Writer result = new StringWriter(); 53 | PrintWriter printWriter = new PrintWriter(result); 54 | ex.setStackTrace(ex.getStackTrace()); 55 | ex.printStackTrace(printWriter); 56 | return result.toString(); 57 | } 58 | 59 | /** 60 | * 收集程序崩溃的设备信息 61 | */ 62 | private String collectCrashDeviceInfo() { 63 | 64 | String versionName = VersionUtil.getVersion(mContext); 65 | String model = android.os.Build.MODEL; 66 | String androidVersion = android.os.Build.VERSION.RELEASE; 67 | String manufacturer = android.os.Build.MANUFACTURER; 68 | 69 | return versionName + " " + model + " " + androidVersion + " " + manufacturer; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/component/ImageLoader.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.component; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.DrawableRes; 5 | import android.widget.ImageView; 6 | import com.bumptech.glide.Glide; 7 | 8 | /** 9 | * Created by HugoXie on 16/4/30. 10 | * 11 | * Email: Hugo3641@gamil.com 12 | * GitHub: https://github.com/xcc3641 13 | * 图片加载类,统一适配(方便换库,方便管理) 14 | */ 15 | public class ImageLoader { 16 | 17 | public static void load(Context context, @DrawableRes int imageRes, ImageView view) { 18 | Glide.with(context).load(imageRes).crossFade().into(view); 19 | } 20 | 21 | public static void clear(Context context) { 22 | Glide.get(context).clearMemory(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/component/NotificationHelper.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.component; 2 | 3 | import android.app.Notification; 4 | import android.app.NotificationManager; 5 | import android.app.PendingIntent; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.support.annotation.NonNull; 9 | import com.xiecc.seeWeather.R; 10 | import com.xiecc.seeWeather.common.utils.SharedPreferenceUtil; 11 | import com.xiecc.seeWeather.modules.main.domain.Weather; 12 | import com.xiecc.seeWeather.modules.main.ui.MainActivity; 13 | 14 | /** 15 | * Created by HugoXie on 2017/5/29. 16 | * 17 | * Email: Hugo3641@gmail.com 18 | * GitHub: https://github.com/xcc3641 19 | * Info: 通知栏 20 | */ 21 | 22 | public class NotificationHelper { 23 | private static final int NOTIFICATION_ID = 233; 24 | 25 | public static void showWeatherNotification(Context context, @NonNull Weather weather) { 26 | Intent intent = new Intent(context, MainActivity.class); 27 | intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 28 | PendingIntent pendingIntent = 29 | PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 30 | Notification.Builder builder = new Notification.Builder(context); 31 | Notification notification = builder.setContentIntent(pendingIntent) 32 | .setContentTitle(weather.basic.city) 33 | .setContentText(String.format("%s 当前温度: %s℃ ", weather.now.cond.txt, weather.now.tmp)) 34 | .setSmallIcon(SharedPreferenceUtil.getInstance().getInt(weather.now.cond.txt, R.mipmap.none)) 35 | .build(); 36 | notification.flags = SharedPreferenceUtil.getInstance().getNotificationModel(); 37 | NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 38 | manager.notify(NOTIFICATION_ID, notification); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/component/OrmLite.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.component; 2 | 3 | import com.litesuits.orm.LiteOrm; 4 | import com.xiecc.seeWeather.BuildConfig; 5 | import com.xiecc.seeWeather.base.BaseApplication; 6 | import com.xiecc.seeWeather.common.C; 7 | 8 | /** 9 | * Created by HugoXie on 16/7/24. 10 | * 11 | * Email: Hugo3641@gamil.com 12 | * GitHub: https://github.com/xcc3641 13 | * Info: 14 | */ 15 | public class OrmLite { 16 | 17 | static LiteOrm sLiteOrm; 18 | 19 | public static LiteOrm getInstance() { 20 | getOrmHolder(); 21 | return sLiteOrm; 22 | } 23 | 24 | private static OrmLite getOrmHolder() { 25 | return OrmHolder.sInstance; 26 | } 27 | 28 | private OrmLite() { 29 | if (sLiteOrm == null) { 30 | sLiteOrm = LiteOrm.newSingleInstance(BaseApplication.getAppContext(), C.ORM_NAME); 31 | } 32 | sLiteOrm.setDebugged(BuildConfig.DEBUG); 33 | } 34 | 35 | private static class OrmHolder { 36 | private static final OrmLite sInstance = new OrmLite(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/component/RxBus.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.component; 2 | 3 | import io.reactivex.Observable; 4 | import io.reactivex.subjects.PublishSubject; 5 | import io.reactivex.subjects.Subject; 6 | 7 | public class RxBus { 8 | private final Subject mBus; 9 | 10 | private RxBus() { 11 | mBus = PublishSubject.create(); 12 | } 13 | 14 | public static RxBus getDefault() { 15 | return RxBusHolder.sInstance; 16 | } 17 | 18 | private static class RxBusHolder { 19 | private static final RxBus sInstance = new RxBus(); 20 | } 21 | 22 | public void post(Object o) { 23 | mBus.onNext(o); 24 | } 25 | 26 | public Observable toObservable(Class eventType) { 27 | return mBus.ofType(eventType); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/about/domain/Version.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.about.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class Version { 6 | 7 | @SerializedName("name") public String name; 8 | @SerializedName("version") public String version; 9 | @SerializedName("changelog") public String changelog; 10 | @SerializedName("updated_at") public int updatedAt; 11 | @SerializedName("versionShort") public String versionShort; 12 | @SerializedName("build") public String build; 13 | @SerializedName("install_url") public String installUrl; 14 | @SerializedName("direct_install_url") public String directInstallUrl; 15 | @SerializedName("update_url") public String updateUrl; 16 | 17 | @SerializedName("binary") public BinaryEntity binary; 18 | 19 | public static class BinaryEntity { 20 | @SerializedName("fsize") public int fsize; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/city/adapter/CityAdapter.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.city.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.CardView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | import butterknife.BindView; 10 | import com.xiecc.seeWeather.R; 11 | import com.xiecc.seeWeather.base.BaseViewHolder; 12 | import com.xiecc.seeWeather.component.AnimRecyclerViewAdapter; 13 | import java.util.ArrayList; 14 | 15 | public class CityAdapter extends AnimRecyclerViewAdapter { 16 | 17 | private Context mContext; 18 | private ArrayList mDataList; 19 | private OnRecyclerViewItemClickListener mOnItemClickListener = null; 20 | 21 | public CityAdapter(Context context, ArrayList dataList) { 22 | mContext = context; 23 | this.mDataList = dataList; 24 | } 25 | 26 | @Override 27 | public CityViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 28 | return new CityViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_city, parent, false)); 29 | } 30 | 31 | @Override 32 | public void onBindViewHolder(final CityViewHolder holder, final int position) { 33 | 34 | holder.bind(mDataList.get(position)); 35 | holder.mCardView.setOnClickListener(v -> mOnItemClickListener.onItemClick(v, position)); 36 | } 37 | 38 | @Override 39 | public int getItemCount() { 40 | return mDataList.size(); 41 | } 42 | 43 | public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) { 44 | this.mOnItemClickListener = listener; 45 | } 46 | 47 | public interface OnRecyclerViewItemClickListener { 48 | void onItemClick(View view, int pos); 49 | } 50 | 51 | class CityViewHolder extends BaseViewHolder { 52 | 53 | @BindView(R.id.item_city) 54 | TextView mItemCity; 55 | @BindView(R.id.cardView) 56 | CardView mCardView; 57 | 58 | public CityViewHolder(View itemView) { 59 | super(itemView); 60 | } 61 | 62 | @Override 63 | protected void bind(String s) { 64 | mItemCity.setText(s); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/city/db/DBManager.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.city.db; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.os.Environment; 6 | import android.support.annotation.Nullable; 7 | import com.xiecc.seeWeather.R; 8 | import com.xiecc.seeWeather.base.BaseApplication; 9 | import com.xiecc.seeWeather.component.PLog; 10 | import java.io.File; 11 | import java.io.FileNotFoundException; 12 | import java.io.FileOutputStream; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | 16 | /** 17 | * Created by hugo on 2015/9/30 0030. 18 | * 数据库管理类 19 | */ 20 | public class DBManager { 21 | 22 | private static String TAG = DBManager.class.getSimpleName(); 23 | public static final String DB_NAME = "china_city.db"; //数据库名字 24 | public static final String PACKAGE_NAME = "com.xiecc.seeWeather"; 25 | public static final String DB_PATH = "/data" + Environment.getDataDirectory().getAbsolutePath() + "/" + 26 | PACKAGE_NAME; //在手机里存放数据库的位置(/data/data/com.xiecc.seeWeather/china_city.db) 27 | private SQLiteDatabase database; 28 | private Context context; 29 | 30 | private DBManager() { 31 | 32 | } 33 | 34 | public static DBManager getInstance() { 35 | return DBManagerHolder.sInstance; 36 | } 37 | 38 | private static final class DBManagerHolder { 39 | public static final DBManager sInstance = new DBManager(); 40 | } 41 | 42 | public SQLiteDatabase getDatabase() { 43 | return database; 44 | } 45 | 46 | 47 | public void openDatabase() { 48 | //PLog.e(TAG, DB_PATH + "/" + DB_NAME); 49 | this.database = this.openDatabase(DB_PATH + "/" + DB_NAME); 50 | } 51 | 52 | @Nullable 53 | private SQLiteDatabase openDatabase(String dbfile) { 54 | 55 | try { 56 | if (!(new File(dbfile).exists())) { 57 | //判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库 58 | InputStream is = BaseApplication.getAppContext().getResources().openRawResource(R.raw.china_city); //欲导入的数据库 59 | FileOutputStream fos = new FileOutputStream(dbfile); 60 | int BUFFER_SIZE = 400000; 61 | byte[] buffer = new byte[BUFFER_SIZE]; 62 | int count; 63 | while ((count = is.read(buffer)) > 0) { 64 | fos.write(buffer, 0, count); 65 | } 66 | fos.close(); 67 | is.close(); 68 | } 69 | return SQLiteDatabase.openOrCreateDatabase(dbfile, null); 70 | } catch (FileNotFoundException e) { 71 | PLog.e("File not found"); 72 | e.printStackTrace(); 73 | } catch (IOException e) { 74 | PLog.e("IO exception"); 75 | e.printStackTrace(); 76 | } 77 | 78 | return null; 79 | } 80 | 81 | public void closeDatabase() { 82 | if (this.database != null) { 83 | this.database.close(); 84 | } 85 | } 86 | } 87 | 88 | 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/city/db/WeatherDB.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.city.db; 2 | 3 | import android.database.Cursor; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import com.xiecc.seeWeather.common.utils.Util; 6 | import com.xiecc.seeWeather.modules.city.domain.City; 7 | import com.xiecc.seeWeather.modules.city.domain.Province; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by hugo on 2015/9/30 0030. 13 | * 封装数据库操作 14 | */ 15 | public class WeatherDB { 16 | 17 | public WeatherDB() { 18 | 19 | } 20 | 21 | public static List loadProvinces(SQLiteDatabase db) { 22 | 23 | List list = new ArrayList<>(); 24 | 25 | Cursor cursor = db.query("T_Province", null, null, null, null, null, null); 26 | 27 | if (cursor.moveToFirst()) { 28 | do { 29 | Province province = new Province(); 30 | province.mProSort = cursor.getInt(cursor.getColumnIndex("ProSort")); 31 | province.mProName = cursor.getString(cursor.getColumnIndex("ProName")); 32 | list.add(province); 33 | } while (cursor.moveToNext()); 34 | } 35 | Util.closeQuietly(cursor); 36 | return list; 37 | } 38 | 39 | public static List loadCities(SQLiteDatabase db, int ProID) { 40 | List list = new ArrayList<>(); 41 | Cursor cursor = db.query("T_City", null, "ProID = ?", new String[] { String.valueOf(ProID) }, null, null, null); 42 | if (cursor.moveToFirst()) { 43 | do { 44 | City city = new City(); 45 | city.mCityName = cursor.getString(cursor.getColumnIndex("CityName")); 46 | city.mProID = ProID; 47 | city.mCitySort = cursor.getInt(cursor.getColumnIndex("CitySort")); 48 | list.add(city); 49 | } while (cursor.moveToNext()); 50 | } 51 | Util.closeQuietly(cursor); 52 | return list; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/city/domain/City.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.city.domain; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import java.io.Serializable; 6 | 7 | public class City implements Parcelable { 8 | 9 | public String mCityName; 10 | public int mProID; 11 | public int mCitySort; 12 | 13 | @Override 14 | public int describeContents() { 15 | return 0; 16 | } 17 | 18 | @Override 19 | public void writeToParcel(Parcel dest, int flags) { 20 | dest.writeString(this.mCityName); 21 | dest.writeInt(this.mProID); 22 | dest.writeInt(this.mCitySort); 23 | } 24 | 25 | public City() { 26 | } 27 | 28 | protected City(Parcel in) { 29 | this.mCityName = in.readString(); 30 | this.mProID = in.readInt(); 31 | this.mCitySort = in.readInt(); 32 | } 33 | 34 | public static final Creator CREATOR = new Creator() { 35 | @Override 36 | public City createFromParcel(Parcel source) { 37 | return new City(source); 38 | } 39 | 40 | @Override 41 | public City[] newArray(int size) { 42 | return new City[size]; 43 | } 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/city/domain/Province.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.city.domain; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | public class Province implements Parcelable { 7 | 8 | public String mProName; 9 | public int mProSort; 10 | 11 | @Override 12 | public String toString() { 13 | return "[mProName] = " + mProName + "\n" + 14 | "[mProSort] = " + mProSort; 15 | } 16 | 17 | @Override 18 | public int describeContents() { 19 | return 0; 20 | } 21 | 22 | @Override 23 | public void writeToParcel(Parcel dest, int flags) { 24 | dest.writeString(this.mProName); 25 | dest.writeInt(this.mProSort); 26 | } 27 | 28 | public Province() { 29 | } 30 | 31 | protected Province(Parcel in) { 32 | this.mProName = in.readString(); 33 | this.mProSort = in.readInt(); 34 | } 35 | 36 | public static final Creator CREATOR = new Creator() { 37 | @Override 38 | public Province createFromParcel(Parcel source) { 39 | return new Province(source); 40 | } 41 | 42 | @Override 43 | public Province[] newArray(int size) { 44 | return new Province[size]; 45 | } 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/launch/FirstActivity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.launch; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import com.xiecc.seeWeather.modules.main.ui.MainActivity; 6 | import io.reactivex.Observable; 7 | import io.reactivex.android.schedulers.AndroidSchedulers; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class FirstActivity extends Activity { 11 | private static final String TAG = FirstActivity.class.getSimpleName(); 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 16 | super.onCreate(savedInstanceState); 17 | Observable.timer(1, TimeUnit.SECONDS) // thanks to XieEDeHeiShou 18 | .observeOn(AndroidSchedulers.mainThread()) 19 | .subscribe(aLong -> { 20 | MainActivity.launch(this); 21 | finish(); 22 | }); 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/adapter/CardCityHelper.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.adapter; 2 | 3 | import android.support.v4.content.ContextCompat; 4 | import android.view.View; 5 | import com.xiecc.seeWeather.R; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class CardCityHelper { 10 | 11 | public static final int SUNNY_CODE = 100; 12 | public static final int RAINY_CODE = 300; 13 | public static final int CLOUDY_CODE = 500; 14 | 15 | private static final String SHANG_HAI = "上海"; 16 | private static final String BEI_JING = "北京"; 17 | private static final String SU_ZHOU = "苏州"; 18 | private static final String OTHER = "其他"; 19 | 20 | private static Map sMap = new HashMap<>(); 21 | 22 | static { 23 | // 上海 24 | sMap.put(new WeatherInfo(SUNNY_CODE, SHANG_HAI), R.mipmap.city_shanghai_sunny); 25 | sMap.put(new WeatherInfo(RAINY_CODE, SHANG_HAI), R.mipmap.city_shanghai_rainy); 26 | sMap.put(new WeatherInfo(CLOUDY_CODE, SHANG_HAI), R.mipmap.city_shanghai_cloudy); 27 | // 北京 28 | sMap.put(new WeatherInfo(SUNNY_CODE, BEI_JING), R.mipmap.city_beijing_sunny); 29 | sMap.put(new WeatherInfo(RAINY_CODE, BEI_JING), R.mipmap.city_beijing_rainy); 30 | sMap.put(new WeatherInfo(CLOUDY_CODE, BEI_JING), R.mipmap.city_beijing_cloudy); 31 | // 苏州 32 | sMap.put(new WeatherInfo(SUNNY_CODE, SU_ZHOU), R.mipmap.city_suzhou_sunny); 33 | sMap.put(new WeatherInfo(RAINY_CODE, SU_ZHOU), R.mipmap.city_suzhou_rain); 34 | sMap.put(new WeatherInfo(CLOUDY_CODE, SU_ZHOU), R.mipmap.city_suzhou_cloudy); 35 | // 其他 36 | sMap.put(new WeatherInfo(SUNNY_CODE, OTHER), R.mipmap.city_other_sunny); 37 | sMap.put(new WeatherInfo(RAINY_CODE, OTHER), R.mipmap.city_other_rainy); 38 | sMap.put(new WeatherInfo(CLOUDY_CODE, OTHER), R.mipmap.city_other_cloudy); 39 | } 40 | 41 | void applyStatus(int code, String city, View view) { 42 | if (code >= 300 && code < 408) { 43 | code = RAINY_CODE; 44 | } else if (code > 100 && code < 300) { 45 | code = CLOUDY_CODE; 46 | } else { 47 | code = SUNNY_CODE; 48 | } 49 | if (!city.matches(String.format("(?:%s|%s|%s)", SU_ZHOU, SHANG_HAI, BEI_JING))) { 50 | city = OTHER; 51 | } 52 | Integer mipRes = sMap.get(new WeatherInfo(code, city)); 53 | if (mipRes != null) { 54 | view.setBackground(ContextCompat.getDrawable(view.getContext(), mipRes)); 55 | } 56 | } 57 | 58 | private static class WeatherInfo { 59 | int weatherCode; 60 | String city; 61 | 62 | public WeatherInfo(int weatherCode, String city) { 63 | this.weatherCode = weatherCode; 64 | this.city = city; 65 | } 66 | 67 | private String code() { 68 | return String.valueOf(String.format("%s%s", weatherCode, city)); 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | return 31 * 17 + code().hashCode(); 74 | } 75 | 76 | @Override 77 | public boolean equals(Object o) { 78 | if (o instanceof WeatherInfo) { 79 | return this.code().equals(((WeatherInfo) o).code()); 80 | } 81 | return super.equals(o); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/adapter/HomePagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.adapter; 2 | 3 | import android.support.design.widget.TabLayout; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentManager; 6 | import android.support.v4.app.FragmentPagerAdapter; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by HugoXie on 16/7/9. 12 | * 13 | * Email: Hugo3641@gamil.com 14 | * GitHub: https://github.com/xcc3641 15 | * Info: 16 | */ 17 | public class HomePagerAdapter extends FragmentPagerAdapter { 18 | 19 | private List fragments = new ArrayList<>(); 20 | private List titles = new ArrayList<>(); 21 | 22 | public HomePagerAdapter(FragmentManager fm) { 23 | super(fm); 24 | } 25 | 26 | public HomePagerAdapter(FragmentManager fm, TabLayout tabLayout) { 27 | super(fm); 28 | } 29 | 30 | public void addTab(Fragment fragment, String title) { 31 | fragments.add(fragment); 32 | titles.add(title); 33 | 34 | } 35 | 36 | /** 37 | * Return the Fragment associated with a specified position. 38 | */ 39 | @Override 40 | public Fragment getItem(int position) { 41 | return fragments.get(position); 42 | } 43 | 44 | /** 45 | * Return the number of views available. 46 | */ 47 | @Override 48 | public int getCount() { 49 | return fragments.size(); 50 | } 51 | 52 | @Override 53 | public CharSequence getPageTitle(int position) { 54 | return titles.get(position); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/AqiEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class AqiEntity implements Serializable { 7 | 8 | @SerializedName("city") 9 | public CityEntity city; 10 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/BasicEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class BasicEntity implements Serializable { 7 | @SerializedName("city") 8 | public String city; 9 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/ChangeCityEvent.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | public class ChangeCityEvent { 4 | 5 | String city; 6 | boolean isSetting; 7 | 8 | public ChangeCityEvent() { 9 | } 10 | 11 | public ChangeCityEvent(boolean isSetting) { 12 | this.isSetting = isSetting; 13 | } 14 | 15 | public ChangeCityEvent(String city) { 16 | this.city = city; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/CityEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class CityEntity implements Serializable { 7 | @SerializedName("aqi") 8 | public String aqi; 9 | @SerializedName("co") 10 | public String co; 11 | @SerializedName("no2") 12 | public String no2; 13 | @SerializedName("o3") 14 | public String o3; 15 | @SerializedName("pm10") 16 | public String pm10; 17 | @SerializedName("pm25") 18 | public String pm25; 19 | @SerializedName("qlty") 20 | public String qlty; 21 | @SerializedName("so2") 22 | public String so2; 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/CityORM.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.litesuits.orm.db.annotation.NotNull; 4 | import com.litesuits.orm.db.annotation.PrimaryKey; 5 | import com.litesuits.orm.db.annotation.Table; 6 | import com.litesuits.orm.db.enums.AssignType; 7 | 8 | /** 9 | * Created by HugoXie on 16/7/24. 10 | * 11 | * Email: Hugo3641@gamil.com 12 | * GitHub: https://github.com/xcc3641 13 | * Info: 14 | */ 15 | @Table("weather_city") 16 | public class CityORM { 17 | 18 | // 指定自增,每个对象需要有一个主键 19 | @PrimaryKey(AssignType.AUTO_INCREMENT) 20 | private int id; 21 | 22 | @NotNull 23 | private String name; 24 | 25 | public CityORM(String name) { 26 | this.name = name; 27 | } 28 | 29 | public int getId() { 30 | return id; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/CondEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class CondEntity implements Serializable { 7 | @SerializedName("code") 8 | public String code; 9 | @SerializedName("txt") 10 | public String txt; 11 | @SerializedName("txt_d") 12 | public String txtDay; 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/DailyForecastEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class DailyForecastEntity implements Serializable { 7 | 8 | @SerializedName("cond") 9 | public CondEntity cond; 10 | @SerializedName("date") 11 | public String date; 12 | @SerializedName("hum") 13 | public String hum; 14 | @SerializedName("pcpn") 15 | public String pcpn; 16 | @SerializedName("pop") 17 | public String pop; 18 | @SerializedName("pres") 19 | public String pres; 20 | /** 21 | * max : 19 22 | * min : 7 23 | */ 24 | 25 | @SerializedName("tmp") 26 | public TmpEntity tmp; 27 | @SerializedName("vis") 28 | public String vis; 29 | 30 | @SerializedName("wind") 31 | public WindEntity wind; 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/HourlyForecastEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class HourlyForecastEntity implements Serializable { 7 | @SerializedName("date") 8 | public String date; 9 | @SerializedName("hum") 10 | public String hum; 11 | @SerializedName("pop") 12 | public String pop; 13 | @SerializedName("pres") 14 | public String pres; 15 | @SerializedName("tmp") 16 | public String tmp; 17 | 18 | @SerializedName("wind") 19 | public WindEntity wind; 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/MultiUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | /** 4 | * Created by HugoXie on 16/7/25. 5 | * 6 | * Email: Hugo3641@gamil.com 7 | * GitHub: https://github.com/xcc3641 8 | * Info: 9 | */ 10 | public class MultiUpdateEvent { 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/NowEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class NowEntity implements Serializable { 7 | 8 | @SerializedName("cond") 9 | public CondEntity cond; 10 | @SerializedName("fl") 11 | public String fl; 12 | @SerializedName("hum") 13 | public String hum; 14 | @SerializedName("pcpn") 15 | public String pcpn; 16 | @SerializedName("pres") 17 | public String pres; 18 | @SerializedName("tmp") 19 | public String tmp; 20 | @SerializedName("vis") 21 | public String vis; 22 | @SerializedName("wind") 23 | public WindEntity wind; 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/SuggestionEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class SuggestionEntity implements Serializable { 7 | @SerializedName("comf") 8 | public ComfEntity comf; 9 | 10 | @SerializedName("cw") 11 | public CwEntity cw; 12 | /** 13 | * brf : 较冷 14 | * txt : 建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。 15 | */ 16 | 17 | @SerializedName("drsg") 18 | public DrsgEntity drsg; 19 | /** 20 | * brf : 较易发 21 | * txt : 昼夜温差较大,较易发生感冒,请适当增减衣服。体质较弱的朋友请注意防护。 22 | */ 23 | 24 | @SerializedName("flu") 25 | public FluEntity flu; 26 | /** 27 | * brf : 较适宜 28 | * txt : 阴天,较适宜进行各种户内外运动。 29 | */ 30 | 31 | @SerializedName("sport") 32 | public SportEntity sport; 33 | /** 34 | * brf : 适宜 35 | * txt : 天气较好,温度适宜,总体来说还是好天气哦,这样的天气适宜旅游,您可以尽情地享受大自然的风光。 36 | */ 37 | 38 | @SerializedName("trav") 39 | public TravEntity trav; 40 | /** 41 | * brf : 最弱 42 | * txt : 属弱紫外线辐射天气,无需特别防护。若长期在户外,建议涂擦SPF在8-12之间的防晒护肤品。 43 | */ 44 | 45 | @SerializedName("uv") 46 | public UvEntity uv; 47 | 48 | public static class ComfEntity implements Serializable { 49 | @SerializedName("brf") 50 | public String brf; 51 | @SerializedName("txt") 52 | public String txt; 53 | } 54 | 55 | public static class CwEntity implements Serializable { 56 | @SerializedName("brf") 57 | public String brf; 58 | @SerializedName("txt") 59 | public String txt; 60 | } 61 | 62 | public static class DrsgEntity implements Serializable { 63 | @SerializedName("brf") 64 | public String brf; 65 | @SerializedName("txt") 66 | public String txt; 67 | } 68 | 69 | public static class FluEntity implements Serializable { 70 | @SerializedName("brf") 71 | public String brf; 72 | @SerializedName("txt") 73 | public String txt; 74 | } 75 | 76 | public static class SportEntity implements Serializable { 77 | @SerializedName("brf") 78 | public String brf; 79 | @SerializedName("txt") 80 | public String txt; 81 | } 82 | 83 | public static class TravEntity implements Serializable { 84 | @SerializedName("brf") 85 | public String brf; 86 | @SerializedName("txt") 87 | public String txt; 88 | } 89 | 90 | public static class UvEntity implements Serializable { 91 | @SerializedName("brf") 92 | public String brf; 93 | @SerializedName("txt") 94 | public String txt; 95 | } 96 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/TmpEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class TmpEntity implements Serializable { 7 | @SerializedName("max") 8 | public String max; 9 | @SerializedName("min") 10 | public String min; 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/Weather.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | import java.util.List; 6 | 7 | public class Weather implements Serializable { 8 | 9 | @SerializedName("aqi") 10 | public AqiEntity aqi; 11 | 12 | @SerializedName("basic") 13 | public BasicEntity basic; 14 | 15 | @SerializedName("now") 16 | public NowEntity now; 17 | 18 | @SerializedName("status") 19 | public String status; 20 | 21 | @SerializedName("suggestion") 22 | public SuggestionEntity suggestion; 23 | 24 | @SerializedName("daily_forecast") 25 | public List dailyForecast; 26 | 27 | @SerializedName("hourly_forecast") 28 | public List hourlyForecast; 29 | 30 | public boolean isValid() { 31 | return aqi != null && now != null && basic != null && suggestion != null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/WeatherAPI.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.Expose; 4 | import com.google.gson.annotations.SerializedName; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class WeatherAPI { 9 | 10 | @SerializedName("HeWeather5") 11 | @Expose 12 | public List mWeathers = new ArrayList<>(); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/domain/WindEntity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.domain; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.io.Serializable; 5 | 6 | public class WindEntity implements Serializable { 7 | @SerializedName("deg") 8 | public String deg; 9 | @SerializedName("dir") 10 | public String dir; 11 | @SerializedName("sc") 12 | public String sc; 13 | @SerializedName("spd") 14 | public String spd; 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/listener/FloatingActionButtonScrollBehavior.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.listener; 2 | 3 | import android.content.Context; 4 | import android.support.design.widget.CoordinatorLayout; 5 | import android.support.design.widget.FloatingActionButton; 6 | import android.support.v4.view.ViewCompat; 7 | import android.util.AttributeSet; 8 | import android.view.View; 9 | 10 | /** 11 | * Created by HugoXie on 16/6/30. 12 | * 13 | * Email: Hugo3641@gamil.com 14 | * GitHub: https://github.com/xcc3641 15 | */ 16 | public class FloatingActionButtonScrollBehavior extends FloatingActionButton.Behavior { 17 | 18 | public FloatingActionButtonScrollBehavior(Context context, AttributeSet attrs) { 19 | super(); 20 | } 21 | 22 | @Override 23 | public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final 24 | FloatingActionButton child, final View directTargetChild, final View target, final int 25 | nestedScrollAxes) { 26 | // 确保是竖直判断的滚动 27 | return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll 28 | (coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); 29 | } 30 | 31 | @Override 32 | public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final 33 | FloatingActionButton child, final View target, final int dxConsumed, final int dyConsumed, 34 | final int dxUnconsumed, final int dyUnconsumed) { 35 | super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, 36 | dxUnconsumed, dyUnconsumed); 37 | if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) { 38 | child.hide(); 39 | } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { 40 | child.show(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/ui/DetailCityActivity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.ui; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import butterknife.BindView; 10 | import com.xiecc.seeWeather.R; 11 | import com.xiecc.seeWeather.base.ToolbarActivity; 12 | import com.xiecc.seeWeather.common.IntentKey; 13 | import com.xiecc.seeWeather.modules.main.adapter.WeatherAdapter; 14 | import com.xiecc.seeWeather.modules.main.domain.Weather; 15 | 16 | /** 17 | * Created by HugoXie on 2017/6/10. 18 | * 19 | * Email: Hugo3641@gmail.com 20 | * GitHub: https://github.com/xcc3641 21 | * Info: 多城市详细页面 22 | */ 23 | 24 | public class DetailCityActivity extends ToolbarActivity { 25 | 26 | @BindView(R.id.recyclerview) 27 | RecyclerView mRecyclerView; 28 | 29 | @Override 30 | protected int layoutId() { 31 | return R.layout.activity_detail; 32 | } 33 | 34 | @Override 35 | public boolean canBack() { 36 | return true; 37 | } 38 | 39 | @Override 40 | protected void onCreate(@Nullable Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | initViewWithData(); 43 | } 44 | 45 | private void initViewWithData() { 46 | Intent intent = getIntent(); 47 | Weather weather = (Weather) intent.getSerializableExtra(IntentKey.WEATHER); 48 | if (weather == null) { 49 | finish(); 50 | } 51 | safeSetTitle(weather.basic.city); 52 | mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 53 | WeatherAdapter mAdapter = new WeatherAdapter(weather); 54 | mRecyclerView.setAdapter(mAdapter); 55 | } 56 | 57 | public static void launch(Context context, Weather weather) { 58 | Intent intent = new Intent(context, DetailCityActivity.class); 59 | intent.putExtra(IntentKey.WEATHER, weather); 60 | context.startActivity(intent); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/main/ui/SharePresenter.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.main.ui; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.widget.LinearLayout; 7 | import butterknife.BindView; 8 | import butterknife.ButterKnife; 9 | import com.xiecc.seeWeather.R; 10 | import com.xiecc.seeWeather.common.utils.WeChatShareUtil; 11 | 12 | /** 13 | * Created by HugoXie on 2017/5/21. 14 | * 15 | * Email: Hugo3641@gmail.com 16 | * GitHub: https://github.com/xcc3641 17 | * Info: 18 | */ 19 | @Deprecated 20 | public class SharePresenter { 21 | 22 | private View mRootView; 23 | 24 | @BindView(R.id.lay_friends) 25 | LinearLayout mLayFriends; 26 | 27 | @BindView(R.id.lay_time_line) 28 | LinearLayout mLayTimeLine; 29 | 30 | public SharePresenter(Context context, String content) { 31 | mRootView = LayoutInflater.from(context).inflate(R.layout.dialog_share, null, false); 32 | ButterKnife.bind(this, mRootView); 33 | initListener(content); 34 | } 35 | 36 | private void initListener(String content) { 37 | mLayFriends.setOnClickListener(click -> WeChatShareUtil.toFriends(mLayFriends.getContext(), content)); 38 | mLayTimeLine.setOnClickListener(click -> WeChatShareUtil.toTimeLine(mLayTimeLine.getContext(), content)); 39 | } 40 | 41 | public View getRootView() { 42 | return mRootView; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/service/AutoUpdateService.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.service; 2 | 3 | import android.app.Service; 4 | import android.content.Intent; 5 | import android.os.IBinder; 6 | import com.xiecc.seeWeather.common.utils.SharedPreferenceUtil; 7 | import com.xiecc.seeWeather.component.NotificationHelper; 8 | import com.xiecc.seeWeather.component.RetrofitSingleton; 9 | import io.reactivex.Observable; 10 | import io.reactivex.disposables.Disposable; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | /** 14 | * Created by HugoXie on 16/4/18. 15 | * 16 | * Email: Hugo3641@gamil.com 17 | * GitHub: https://github.com/xcc3641 18 | */ 19 | public class AutoUpdateService extends Service { 20 | 21 | private final String TAG = AutoUpdateService.class.getSimpleName(); 22 | private Disposable mDisposable; 23 | private boolean mIsUnSubscribed = true; 24 | 25 | @Override 26 | public IBinder onBind(Intent intent) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public void onCreate() { 32 | super.onCreate(); 33 | } 34 | 35 | @Override 36 | public int onStartCommand(Intent intent, int flags, int startId) { 37 | synchronized (this) { 38 | unSubscribed(); 39 | if (mIsUnSubscribed) { 40 | unSubscribed(); 41 | if (SharedPreferenceUtil.getInstance().getAutoUpdate() != 0) { 42 | mDisposable = Observable.interval(SharedPreferenceUtil.getInstance().getAutoUpdate(), TimeUnit.HOURS) 43 | .doOnNext(aLong -> { 44 | mIsUnSubscribed = false; 45 | fetchDataByNetWork(); 46 | }) 47 | .subscribe(); 48 | } 49 | } 50 | } 51 | return START_REDELIVER_INTENT; 52 | } 53 | 54 | private void unSubscribed() { 55 | mIsUnSubscribed = true; 56 | if (mDisposable != null && !mDisposable.isDisposed()) { 57 | mDisposable.dispose(); 58 | } 59 | } 60 | 61 | @Override 62 | public boolean stopService(Intent name) { 63 | return super.stopService(name); 64 | } 65 | 66 | private void fetchDataByNetWork() { 67 | String cityName = SharedPreferenceUtil.getInstance().getCityName(); 68 | RetrofitSingleton.getInstance() 69 | .fetchWeather(cityName) 70 | .subscribe(weather -> NotificationHelper.showWeatherNotification(AutoUpdateService.this, weather)); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/xiecc/seeWeather/modules/setting/ui/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package com.xiecc.seeWeather.modules.setting.ui; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import com.xiecc.seeWeather.R; 7 | import com.xiecc.seeWeather.base.ToolbarActivity; 8 | 9 | public class SettingActivity extends ToolbarActivity { 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | getToolbar().setTitle("设置"); 14 | getFragmentManager().beginTransaction().replace(R.id.frameLayout, new SettingFragment()).commit(); 15 | } 16 | 17 | @Override 18 | protected int layoutId() { 19 | return R.layout.activity_setting; 20 | } 21 | 22 | @Override 23 | protected void onPause() { 24 | super.onPause(); 25 | } 26 | 27 | @Override 28 | public boolean canBack() { 29 | return true; 30 | } 31 | 32 | @Override 33 | protected void onResume() { 34 | super.onResume(); 35 | } 36 | 37 | public static void launch(Context context) { 38 | context.startActivity(new Intent(context, SettingActivity.class)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_right.xml: -------------------------------------------------------------------------------- 1 | 19 | 20 | 22 | 26 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/anim/zoom_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/anim/zoom_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/icon_city.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/icon_cloth.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/icon_flu.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/icon_humidity.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/icon_sport.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/icon_temp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/icon_wind.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/about_1.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/about_2.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/about_3.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bug.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/code.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/github.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/home.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_icon_wechat.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_icon_wechat_line.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_location.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_about.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_city.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_set.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_multi_cities.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_city.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_cloth.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_flu.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_humidity.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_sport.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_temp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_time.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_travel.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_wind.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/mine.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/pay.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bar_states.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/update.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_choice_city.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 16 | 17 | 21 | 22 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 16 | 17 | 22 | 23 | 24 | 25 | 36 | 37 | 38 | 39 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 18 | 19 | 20 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 21 | 29 | 34 | 41 | 42 | 43 | 52 | 57 | 63 | 64 | 65 | 66 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_share.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 21 | 22 | 28 | 32 | 37 | 38 | 39 | 46 | 50 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_update.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | 20 | 21 | 30 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_weather.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 19 | 28 | 29 | 30 | 37 | 38 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_multicity.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 16 | 17 | 18 | 19 | 27 | 28 | 32 | 33 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_webview.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_city.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 20 | 21 | 25 | 26 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_forecast.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_forecast_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 21 | 22 | 29 | 30 | 38 | 39 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_hour_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_hour_info_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 22 | 23 | 31 | 32 | 40 | 41 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_multi_city.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/nav_header_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/part_tab_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/part_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/part_toolbar_indicator.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/progressbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/menu/activity_main_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 14 | 15 | 16 | 17 | 18 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/menu/multi_city_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/first_backpng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-hdpi/first_backpng.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-night/header_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-night/header_back.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-night/sun_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-night/sun_main.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_beijing_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_beijing_cloudy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_beijing_rainy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_beijing_rainy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_beijing_sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_beijing_sunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_other_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_other_cloudy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_other_rainy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_other_rainy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_other_sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_other_sunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_shanghai_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_shanghai_cloudy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_shanghai_rainy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_shanghai_rainy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_shanghai_sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_shanghai_sunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_suzhou_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_suzhou_cloudy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_suzhou_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_suzhou_rain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/city_suzhou_sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/city_suzhou_sunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/dialog_icon_city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/dialog_icon_city.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/empty.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/erro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/erro.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/header_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/header_back.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/iconpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/iconpoint.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/none.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/setting_header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/setting_header.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/sun_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/sun_main.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_cloudy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_cloudytosunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_cloudytosunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_fog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_fog.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_heavy_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_heavy_rain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_light_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_light_rain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_snow.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_sunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_thunder_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_thunder_rain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_thunderstorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_thunderstorm.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_one_windy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_one_windy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_cloudy.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_cloudytosunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_cloudytosunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_fog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_fog.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_hail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_hail.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_hailrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_hailrain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_haze.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_haze.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_light_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_light_rain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_rain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_snowrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_snowrain.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_sunny.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/type_two_thunderstorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/mipmap-xhdpi/type_two_thunderstorm.png -------------------------------------------------------------------------------- /app/src/main/res/raw/china_city.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/app/src/main/res/raw/china_city.db -------------------------------------------------------------------------------- /app/src/main/res/transition-v21/activity_side.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/transition/activity_explode.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/transition/activity_fade.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/transition/activity_side.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #201D45 4 | #201D45 5 | @android:color/background_light 6 | #FC413D 7 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 就看天气 4 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 0dp 7 | 8dp 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #106c99 4 | #0D4A6A 5 | #FC413D 6 | 7 | #0D4A6A 8 | #201D45 9 | 10 | #8C8C8C 11 | 12 | 13 | #106c99 14 | 15 | #C1C1C1 16 | #696969 17 | 18 | #A88418 19 | #FFE498 20 | #FFC000 21 | 22 | #728288 23 | #D2E0E6 24 | #A4BCC6 25 | 26 | #035E8E 27 | #B2E8FE 28 | #58D2FA 29 | 30 | #60d3d3d3 31 | #6f6f6f 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 256dp 3 | 16dp 4 | 16dp 5 | 6 | 7 | 16dp 8 | 160dp 9 | 10 | 16dp 11 | 16dp 12 | 13 | 0dp 14 | 8dp 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 就看天气 3 | Open navigation drawer 4 | Close navigation drawer 5 | 6 | 开启多城市 7 | 网络不好(˵¯͒⌢͗¯͒˵) 8 | Main2Activity 9 | 就看天气 10 | Settings 11 | 出了点小问题,别担心,( •̀ .̫ •́ )✧ 12 | 就看天气 Version- 13 | 找不到版本号 14 | 欢迎使用“就看天气”,希望每天都是好心情,您可以在http://www.wandoujia.com/apps/com.xiecc.seeWeather下载 15 | 分享-就看天气 16 | xcc3641@163.com 17 | Copyright 2016 HugoXie Licensed under the Apache License, Version 2.0 (the \"License\") 18 | https://github.com/xcc3641/SeeWeather 19 | https://github.com/xcc3641/SeeWeather/blob/master/README.md 20 | 21 | 更换图标 22 | 选择城市 23 | 设置 24 | 关于 25 | 多城市管理 26 | 再按一次退出 27 | 加载完毕,✺◟(∗❛ัᴗ❛ั∗)◞✺, 28 | 定位失败,加载默认城市 29 | 30 | 就看天气该应用就是如同它的名字一样,只做一个单纯、简单的看天气软件。这么多天气软件,你选择了我,这是我的幸运。\n从15年10月上线,到目前经历两次重大改版,一次代码的重构,一次界面的大幅度改动,目的都是为了你们。 31 | 在开源的过程中,收到了很多来自有趣的你们的邮件。\n我也曾遇到过棘手的问题无处咨询又谷歌不到。那个时候的我,也可能是现在的你。所以我希望能够帮助到你。 32 | • RxJava: github.com/ReactiveX/RxJava\n• RxAndroid: github.com/ReactiveX/RxAndroid\n• Retrofit: github.com/square/retrofit\n• Glide: github.com/bumptech/glide\n• YujunZhu 设计师提供多城市卡片设计\n• 和风天气提供数据支持\n• 高德定位提供位置定位服务 33 | https://www.wenjuan.com/s/YbqANfc/ 34 | 35 | 图标一 36 | 图标二 37 | 38 | 39 | 40 | 禁止刷新 41 | 每1小时 42 | 每3小时 43 | 每6小时 44 | 45 | 46 | Blocks 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 16 | 17 | 21 | 22 | 28 | 29 | 33 | 34 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/xml/about.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 16 | 20 | 24 | 25 | 26 | 30 | 34 | 38 | 39 | 40 | 43 | 46 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/xml/setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 11 | 12 | 13 | 16 | 19 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply from: 'config.gradle' 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | mavenCentral() 7 | google() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:2.3.3' 11 | classpath "me.tatarka:gradle-retrolambda:3.7.0" 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | google() 19 | maven { url 'https://jitpack.io' } 20 | } 21 | } 22 | 23 | task clean(type: Delete) { 24 | delete rootProject.buildDir 25 | } -------------------------------------------------------------------------------- /builddebug: -------------------------------------------------------------------------------- 1 | cd `dirname $0` 2 | ./gradlew assembleDebug 3 | -------------------------------------------------------------------------------- /changeLog.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | 3 | ---- 4 | 5 | v2.3 6 | - [新增] 卡片 UI(含有北京,上海,苏州) 7 | - [优化] 代码逻辑和规范 8 | - [美化] 关于页面沉浸式 9 | - [新增] 多城市订阅数量 10 | 11 | 12 | v2.2 13 | - [新增] 多城市管理 14 | - [新增] Bug反馈和意见 15 | - [改版] 首页UI 更丰富 16 | - [美化] 关于页面 17 | - [美化] 部分图标 18 | 19 | v2.1 20 | - [修复] 定位逻辑 21 | - [优化] SP的统一化 22 | - [优化] Error界面 23 | - [更新] 新的天气 ICON 24 | - [更新] 通知栏提醒(后台可能需要白名单,不然无法自动更新) 25 | - [优化] 自动更新频率(0 为不自动更新) 26 | 27 | 28 | v2.0 29 | - 重构代码,全新UI,升级体验 30 | - 就看天气——是一款遵循**Material Design**风格的只看天气的APP。无流氓权限,无自启,xxx,用最少的权限做最优的体验。 31 | - 卡片展现(当前天气情况,未来几小时天气情况,生活建议,一周七天概况) 32 | - 彩蛋(自动夜间状态) 33 | - 补全城市(第一版本因为自己偷懒所以城市有缺陷对不起各位) 34 | - 缓存数据,减少网络请求,保证离线查看 35 | - 内置两套图标(设置里更改) 36 | -------------------------------------------------------------------------------- /clean: -------------------------------------------------------------------------------- 1 | ./gradlew clean -------------------------------------------------------------------------------- /config.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | android = [ 3 | 4 | buildToolsVersion: '26.0.1', 5 | supportVersion : '26.0.2', 6 | minSdkVersion : 19, 7 | compileSdkVersion: 26, 8 | targetSdkVersion : 25, 9 | applicationId : "com.xiecc.seeWeather", 10 | versionCode : 34, 11 | versionName : "2.3.1", 12 | resConfigs : "zh", 13 | ] 14 | 15 | weather = [ 16 | name : "WeatherKey", 17 | value: "282f3846df6b41178e4a2218ae083ea7" 18 | ] 19 | 20 | fir = [ 21 | name : "FirToken", 22 | value: "7db041d0c3013b63e4bed2a554f02d85" 23 | ] 24 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## Project-wide Gradle settings. 2 | # 3 | # For more details on how to configure your build environment visit 4 | # http://www.gradle.org/docs/current/userguide/build_environment.html 5 | # 6 | # Specifies the JVM arguments used for the daemon process. 7 | # The setting is particularly useful for tweaking memory settings. 8 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 10 | # 11 | # When configured, Gradle will run in incubating parallel mode. 12 | # This option should only be used with decoupled projects. More details, visit 13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 14 | # org.gradle.parallel=true 15 | #Sat May 28 20:20:10 CST 2016 16 | systemProp.http.proxyHost=127.0.0.1 17 | systemProp.http.proxyPort=1080 18 | android.useDeprecatedNdk=true 19 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Apr 22 14:01:53 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /images/day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/images/day.png -------------------------------------------------------------------------------- /images/night.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/images/night.png -------------------------------------------------------------------------------- /images/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcc3641/SeeWeather/1e3485179a0d91eb8d781287b2f45518f0d50920/images/splash.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------