indexList) {
43 | this.indexList = indexList;
44 | }
45 |
46 | public MiRealTime getRealTime() {
47 | return realTime;
48 | }
49 |
50 | public void setRealTime(MiRealTime realTime) {
51 | this.realTime = realTime;
52 | }
53 |
54 | public MiToday getToday() {
55 | return today;
56 | }
57 |
58 | public void setToday(MiToday today) {
59 | this.today = today;
60 | }
61 |
62 | public MiToday getYesterday() {
63 | return yesterday;
64 | }
65 |
66 | public void setYesterday(MiToday yesterday) {
67 | this.yesterday = yesterday;
68 | }
69 |
70 | @Override
71 | public String toString() {
72 | return "MiWeather{" +
73 | "forecast=" + forecast +
74 | ", realTime=" + realTime +
75 | ", aqi=" + aqi +
76 | ", indexList=" + indexList +
77 | ", today=" + today +
78 | ", yesterday=" + yesterday +
79 | '}';
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/data/http/interceptor/HttpRequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.data.http.interceptor;
2 |
3 | import java.io.IOException;
4 |
5 | import okhttp3.Interceptor;
6 | import okhttp3.Response;
7 |
8 | /**
9 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
10 | * 16/2/25
11 | */
12 | public class HttpRequestInterceptor implements Interceptor {
13 |
14 | @Override
15 | public Response intercept(Chain chain) throws IOException {
16 | return null;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/data/http/service/EnvironmentCloudWeatherService.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.data.http.service;
2 |
3 | import com.baronzhang.android.weather.data.http.entity.envicloud.EnvironmentCloudCityAirLive;
4 | import com.baronzhang.android.weather.data.http.entity.envicloud.EnvironmentCloudForecast;
5 | import com.baronzhang.android.weather.data.http.entity.envicloud.EnvironmentCloudWeatherLive;
6 |
7 | import retrofit2.http.GET;
8 | import retrofit2.http.Path;
9 | import rx.Observable;
10 |
11 | /**
12 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
13 | * 2017/2/16
14 | */
15 | public interface EnvironmentCloudWeatherService {
16 |
17 | /**
18 | * 获取指定城市的实时天气
19 | *
20 | * API地址:http://service.envicloud.cn:8082/v2/weatherlive/YMFYB256AGFUZZE0ODQ3MZM1MZE2NTU=/101020100
21 | *
22 | * @param cityId 城市id
23 | * @return Observable
24 | */
25 | @GET("/v2/weatherlive/YMFYB256AGFUZZE0ODQ3MZM1MZE2NTU=/{cityId}")
26 | Observable getWeatherLive(@Path("cityId") String cityId);
27 |
28 | /**
29 | * 获取指定城市7日天气预报
30 | *
31 | * API地址:http://service.envicloud.cn:8082/v2/weatherforecast/YMFYB256AGFUZZE0ODQ3MZM1MZE2NTU=/101020100
32 | *
33 | * @param cityId 城市id
34 | * @return Observable
35 | */
36 | @GET("/v2/weatherforecast/YMFYB256AGFUZZE0ODQ3MZM1MZE2NTU=/{cityId}")
37 | Observable getWeatherForecast(@Path("cityId") String cityId);
38 |
39 | /**
40 | * 获取指定城市的实时空气质量
41 | *
42 | * API地址:http://service.envicloud.cn:8082/v2/cityairlive/YMFYB256AGFUZZE0ODQ3MZM1MZE2NTU=/101020100
43 | *
44 | * @param cityId 城市id
45 | * @return Observable
46 | */
47 | @GET("/v2/cityairlive/YMFYB256AGFUZZE0ODQ3MZM1MZE2NTU=/{cityId}")
48 | Observable getAirLive(@Path("cityId") String cityId);
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/data/http/service/WeatherService.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.data.http.service;
2 |
3 | import com.baronzhang.android.weather.data.http.entity.know.KnowWeather;
4 | import com.baronzhang.android.weather.data.http.entity.mi.MiWeather;
5 | import retrofit2.http.GET;
6 | import retrofit2.http.Path;
7 | import retrofit2.http.Query;
8 | import rx.Observable;
9 |
10 | /**
11 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
12 | * 16/2/25
13 | */
14 | public interface WeatherService {
15 |
16 | /**
17 | * http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101010100
18 | *
19 | * @param cityId 城市ID
20 | * @return 天气数据
21 | */
22 | @GET("weather")
23 | Observable getMiWeather(@Query("cityId") String cityId);
24 |
25 |
26 | /**
27 | * http://knowweather.duapp.com/v1.0/weather/101010100
28 | *
29 | * @param cityId 城市ID
30 | * @return 天气数据
31 | */
32 | @GET("v1.0/weather/{cityId}")
33 | Observable getKnowWeather(@Path("cityId") String cityId);
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/data/preference/ConfigurationListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 BaronZhang(BaronZ88)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.baronzhang.android.weather.data.preference;
17 |
18 | public interface ConfigurationListener {
19 |
20 | void onConfigurationChanged(WeatherSettings pref, Object newValue);
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/data/preference/WeatherSettings.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.data.preference;
2 |
3 | /**
4 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
5 | */
6 | public enum WeatherSettings {
7 |
8 | /*默认配置项*/
9 | SETTINGS_FIRST_USE("first_use", Boolean.TRUE),
10 |
11 | SETTINGS_CURRENT_CITY_ID("current_city_id", "");
12 |
13 | private final String mId;
14 | private final Object mDefaultValue;
15 |
16 | WeatherSettings(String id, Object defaultValue) {
17 | this.mId = id;
18 | this.mDefaultValue = defaultValue;
19 | }
20 |
21 | public String getId() {
22 | return this.mId;
23 | }
24 |
25 | public Object getDefaultValue() {
26 | return this.mDefaultValue;
27 | }
28 |
29 | public static WeatherSettings fromId(String id) {
30 | WeatherSettings[] values = values();
31 | for (WeatherSettings value : values) {
32 | if (value.mId.equals(id)) {
33 | return value;
34 | }
35 | }
36 | return null;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/di/component/ApplicationComponent.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.di.component;
2 |
3 | import android.content.Context;
4 |
5 | import com.baronzhang.android.weather.WeatherApplication;
6 | import com.baronzhang.android.weather.di.module.ApplicationModule;
7 |
8 | import javax.inject.Singleton;
9 |
10 | import dagger.Component;
11 |
12 | /**
13 | * @author 张磊 (baron[dot]zhanglei[at]gmail[dot]com)
14 | * 2016/11/30
15 | */
16 | @Singleton
17 | @Component(modules = {ApplicationModule.class})
18 | public interface ApplicationComponent {
19 |
20 | WeatherApplication getApplication();
21 |
22 | Context getContext();
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/di/component/PresenterComponent.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.di.component;
2 |
3 | import com.baronzhang.android.weather.di.module.ApplicationModule;
4 | import com.baronzhang.android.weather.feature.home.drawer.DrawerMenuPresenter;
5 | import com.baronzhang.android.weather.feature.selectcity.SelectCityPresenter;
6 |
7 | import javax.inject.Singleton;
8 |
9 | import dagger.Component;
10 | import com.baronzhang.android.weather.feature.home.HomePagePresenter;
11 |
12 | /**
13 | * @author 张磊 (baron[dot]zhanglei[at]gmail[dot]com)
14 | * 2016/12/2
15 | */
16 | @Singleton
17 | @Component(modules = {ApplicationModule.class})
18 | public interface PresenterComponent {
19 |
20 | void inject(HomePagePresenter presenter);
21 |
22 | void inject(SelectCityPresenter presenter);
23 |
24 | void inject(DrawerMenuPresenter presenter);
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/di/module/ApplicationModule.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.di.module;
2 |
3 | import android.content.Context;
4 |
5 | import com.baronzhang.android.weather.WeatherApplication;
6 |
7 | import javax.inject.Singleton;
8 |
9 | import dagger.Module;
10 | import dagger.Provides;
11 |
12 | /**
13 | * @author 张磊 (baronzhang[at]anjuke[dot]com)
14 | * 2016/11/30
15 | */
16 | @Module
17 | public class ApplicationModule {
18 |
19 | private Context context;
20 |
21 | public ApplicationModule(Context context) {
22 |
23 | this.context = context;
24 | }
25 |
26 | @Provides
27 | @Singleton
28 | WeatherApplication provideApplication() {
29 |
30 | return (WeatherApplication) context.getApplicationContext();
31 | }
32 |
33 | @Provides
34 | @Singleton
35 | Context provideContext() {
36 |
37 | return context;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/di/scope/ActivityScoped.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.di.scope;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 |
7 | import javax.inject.Scope;
8 |
9 | /**
10 | * @author 张磊 (baronzhang[at]anjuke[dot]com)
11 | * 2016/12/1
12 | */
13 | @Scope
14 | @Documented
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface ActivityScoped {
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/DetailAdapter.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home;
2 |
3 | import androidx.recyclerview.widget.RecyclerView;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ImageView;
8 | import android.widget.TextView;
9 |
10 | import com.baronzhang.android.weather.base.BaseRecyclerViewAdapter;
11 | import com.baronzhang.android.weather.R;
12 | import com.baronzhang.android.weather.data.WeatherDetail;
13 |
14 | import java.util.List;
15 |
16 | import butterknife.BindView;
17 | import butterknife.ButterKnife;
18 |
19 | /**
20 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
21 | * 2016/07/06
22 | */
23 | public class DetailAdapter extends BaseRecyclerViewAdapter {
24 |
25 | private List details;
26 |
27 | public DetailAdapter(List details) {
28 | this.details = details;
29 | }
30 |
31 | @Override
32 | public DetailAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
33 | View itemView = LayoutInflater.from(parent.getContext())
34 | .inflate(R.layout.item_detail, parent, false);
35 | return new ViewHolder(itemView, this);
36 | }
37 |
38 | @Override
39 | public void onBindViewHolder(DetailAdapter.ViewHolder holder, int position) {
40 | WeatherDetail detail = details.get(position);
41 | holder.detailIconImageView.setImageResource(detail.getIconResourceId());
42 | holder.detailKeyTextView.setText(detail.getKey());
43 | holder.detailValueTextView.setText(detail.getValue());
44 | }
45 |
46 | @Override
47 | public int getItemCount() {
48 | return details == null ? 0 : details.size();
49 | }
50 |
51 | static class ViewHolder extends RecyclerView.ViewHolder {
52 |
53 | @BindView(R.id.detail_icon_image_view)
54 | ImageView detailIconImageView;
55 | @BindView(R.id.detail_key_text_view)
56 | TextView detailKeyTextView;
57 | @BindView(R.id.detail_value_text_view)
58 | TextView detailValueTextView;
59 |
60 | ViewHolder(View itemView, DetailAdapter adapter) {
61 | super(itemView);
62 | ButterKnife.bind(this, itemView);
63 | itemView.setOnClickListener(v -> adapter.onItemHolderClick(DetailAdapter.ViewHolder.this));
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/ForecastAdapter.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home;
2 |
3 | import android.annotation.SuppressLint;
4 | import androidx.recyclerview.widget.RecyclerView;
5 | import android.text.TextUtils;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.baronzhang.android.weather.base.BaseRecyclerViewAdapter;
13 | import com.baronzhang.android.weather.R;
14 | import com.baronzhang.android.weather.data.db.entities.minimalist.WeatherForecast;
15 |
16 | import java.util.List;
17 |
18 | import butterknife.BindView;
19 | import butterknife.ButterKnife;
20 |
21 | /**
22 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
23 | * 16/6/23
24 | */
25 | public class ForecastAdapter extends BaseRecyclerViewAdapter {
26 |
27 | private List weatherForecasts;
28 |
29 | public ForecastAdapter(List weatherForecasts) {
30 | this.weatherForecasts = weatherForecasts;
31 | }
32 |
33 | @Override
34 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
35 | View itemView = LayoutInflater.from(parent.getContext())
36 | .inflate(R.layout.item_forecast, parent, false);
37 | return new ViewHolder(itemView, this);
38 | }
39 |
40 | @SuppressLint("SetTextI18n")
41 | @Override
42 | public void onBindViewHolder(ForecastAdapter.ViewHolder holder, int position) {
43 | WeatherForecast weatherForecast = weatherForecasts.get(position);
44 | holder.weekTextView.setText(weatherForecast.getWeek());
45 | holder.dateTextView.setText(weatherForecast.getDate());
46 | holder.weatherIconImageView.setImageResource(R.mipmap.ic_launcher);
47 | holder.weatherTextView.setText(TextUtils.isEmpty(weatherForecast.getWeather()) ?
48 | (weatherForecast.getWeatherDay().equals(weatherForecast.getWeatherNight()) ?
49 | weatherForecast.getWeatherDay() : weatherForecast.getWeatherDay() + "转" + weatherForecast.getWeatherNight())
50 | : weatherForecast.getWeather());
51 | holder.tempMaxTextView.setText(weatherForecast.getTempMax() + "°");
52 | holder.tempMinTextView.setText(weatherForecast.getTempMin() + "°");
53 | }
54 |
55 | @Override
56 | public int getItemCount() {
57 | return weatherForecasts == null ? 0 : weatherForecasts.size();
58 | }
59 |
60 | static class ViewHolder extends RecyclerView.ViewHolder {
61 |
62 | @BindView(R.id.week_text_view)
63 | TextView weekTextView;
64 | @BindView(R.id.date_text_view)
65 | TextView dateTextView;
66 | @BindView(R.id.weather_icon_image_view)
67 | ImageView weatherIconImageView;
68 | @BindView(R.id.weather_text_view)
69 | TextView weatherTextView;
70 | @BindView(R.id.temp_max_text_view)
71 | TextView tempMaxTextView;
72 | @BindView(R.id.temp_min_text_view)
73 | TextView tempMinTextView;
74 |
75 | ViewHolder(View itemView, ForecastAdapter adapter) {
76 | super(itemView);
77 | ButterKnife.bind(this, itemView);
78 | itemView.setOnClickListener(v -> adapter.onItemHolderClick(ViewHolder.this));
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/HomePageComponent.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home;
2 |
3 | import com.baronzhang.android.weather.di.component.ApplicationComponent;
4 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
5 |
6 | import dagger.Component;
7 |
8 | /**
9 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
10 | * 2016/11/29
11 | */
12 | @ActivityScoped
13 | @Component(modules = HomePageModule.class, dependencies = ApplicationComponent.class)
14 | public interface HomePageComponent {
15 |
16 | void inject(MainActivity mainActivity);
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/HomePageContract.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home;
2 |
3 | import com.baronzhang.android.weather.data.db.entities.minimalist.Weather;
4 | import com.baronzhang.android.weather.base.BasePresenter;
5 | import com.baronzhang.android.weather.base.BaseView;
6 |
7 | /**
8 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
9 | */
10 | public interface HomePageContract {
11 |
12 | interface View extends BaseView {
13 |
14 | void displayWeatherInformation(Weather weather);
15 | }
16 |
17 | interface Presenter extends BasePresenter {
18 |
19 | void loadWeather(String cityId, boolean refreshNow);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/HomePageModule.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home;
2 |
3 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
4 | import com.baronzhang.android.weather.feature.home.HomePagePresenter;
5 |
6 | import dagger.Module;
7 | import dagger.Provides;
8 |
9 | import com.baronzhang.android.weather.feature.home.HomePageContract;
10 |
11 | /**
12 | * This is a Dagger module. We use this to pass in the View dependency to the
13 | * {@link HomePagePresenter}
14 | *
15 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
16 | * 2016/11/30
17 | */
18 | @Module
19 | public class HomePageModule {
20 |
21 | private HomePageContract.View view;
22 |
23 | public HomePageModule(HomePageContract.View view) {
24 |
25 | this.view = view;
26 | }
27 |
28 | @Provides
29 | @ActivityScoped
30 | HomePageContract.View provideHomePageContractView() {
31 | return view;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/HomePagePresenter.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home;
2 |
3 | import android.content.Context;
4 | import android.widget.Toast;
5 |
6 | import com.baronzhang.android.library.util.RxSchedulerUtils;
7 | import com.baronzhang.android.weather.data.db.dao.WeatherDao;
8 | import com.baronzhang.android.weather.data.preference.PreferenceHelper;
9 | import com.baronzhang.android.weather.data.preference.WeatherSettings;
10 | import com.baronzhang.android.weather.data.repository.WeatherDataRepository;
11 | import com.baronzhang.android.weather.di.component.DaggerPresenterComponent;
12 | import com.baronzhang.android.weather.di.module.ApplicationModule;
13 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
14 |
15 | import javax.inject.Inject;
16 |
17 | import rx.Subscription;
18 | import rx.subscriptions.CompositeSubscription;
19 |
20 | /**
21 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
22 | */
23 | @ActivityScoped
24 | public final class HomePagePresenter implements HomePageContract.Presenter {
25 |
26 | private final Context context;
27 | private final HomePageContract.View weatherView;
28 |
29 | private CompositeSubscription subscriptions;
30 |
31 | @Inject
32 | WeatherDao weatherDao;
33 |
34 | @Inject
35 | HomePagePresenter(Context context, HomePageContract.View view) {
36 |
37 | this.context = context;
38 | this.weatherView = view;
39 | this.subscriptions = new CompositeSubscription();
40 | weatherView.setPresenter(this);
41 |
42 | DaggerPresenterComponent.builder()
43 | .applicationModule(new ApplicationModule(context))
44 | .build().inject(this);
45 | }
46 |
47 | @Override
48 | public void subscribe() {
49 | String cityId = PreferenceHelper.getSharedPreferences().getString(WeatherSettings.SETTINGS_CURRENT_CITY_ID.getId(), "");
50 | loadWeather(cityId, false);
51 | }
52 |
53 | @Override
54 | public void loadWeather(String cityId, boolean refreshNow) {
55 |
56 | Subscription subscription = WeatherDataRepository.getWeather(context, cityId, weatherDao, refreshNow)
57 | .compose(RxSchedulerUtils.normalSchedulersTransformer())
58 | .subscribe(weatherView::displayWeatherInformation, throwable -> {
59 | Toast.makeText(context, throwable.getMessage(), Toast.LENGTH_LONG).show();
60 | });
61 | subscriptions.add(subscription);
62 | }
63 |
64 | @Override
65 | public void unSubscribe() {
66 | subscriptions.clear();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/LifeIndexAdapter.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home;
2 |
3 | import android.content.Context;
4 | import android.graphics.drawable.Drawable;
5 | import androidx.recyclerview.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.baronzhang.android.weather.base.BaseRecyclerViewAdapter;
13 | import com.baronzhang.android.weather.R;
14 | import com.baronzhang.android.weather.data.db.entities.minimalist.LifeIndex;
15 |
16 | import java.util.List;
17 |
18 | import butterknife.BindView;
19 | import butterknife.ButterKnife;
20 |
21 | import static com.baronzhang.android.weather.R.drawable.ic_index_sunscreen;
22 |
23 | /**
24 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
25 | * 2016/12/13
26 | */
27 | public class LifeIndexAdapter extends BaseRecyclerViewAdapter {
28 |
29 | private Context context;
30 | private List indexList;
31 |
32 | public LifeIndexAdapter(Context context, List indexList) {
33 | this.context = context;
34 | this.indexList = indexList;
35 | }
36 |
37 | @Override
38 | public LifeIndexAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
39 | View itemView = LayoutInflater.from(parent.getContext())
40 | .inflate(R.layout.item_life_index, parent, false);
41 | return new ViewHolder(itemView, this);
42 | }
43 |
44 | @Override
45 | public void onBindViewHolder(LifeIndexAdapter.ViewHolder holder, int position) {
46 | LifeIndex index = indexList.get(position);
47 | holder.indexIconImageView.setImageDrawable(getIndexDrawable(context, index.getName()));
48 | holder.indexLevelTextView.setText(index.getIndex());
49 | holder.indexNameTextView.setText(index.getName());
50 | }
51 |
52 | @Override
53 | public int getItemCount() {
54 | return indexList == null ? 0 : indexList.size();
55 | }
56 |
57 | static class ViewHolder extends RecyclerView.ViewHolder {
58 |
59 | @BindView(R.id.index_icon_image_view)
60 | ImageView indexIconImageView;
61 | @BindView(R.id.index_level_text_view)
62 | TextView indexLevelTextView;
63 | @BindView(R.id.index_name_text_view)
64 | TextView indexNameTextView;
65 |
66 | ViewHolder(View itemView, LifeIndexAdapter adapter) {
67 | super(itemView);
68 | ButterKnife.bind(this, itemView);
69 | itemView.setOnClickListener(v -> adapter.onItemHolderClick(LifeIndexAdapter.ViewHolder.this));
70 | }
71 | }
72 |
73 | private Drawable getIndexDrawable(Context context, String indexName) {
74 |
75 |
76 | int colorResourceId = ic_index_sunscreen;
77 | if (indexName.contains("防晒")) {
78 | colorResourceId = ic_index_sunscreen;
79 | } else if (indexName.contains("穿衣")) {
80 | colorResourceId = R.drawable.ic_index_dress;
81 | } else if (indexName.contains("运动")) {
82 | colorResourceId = R.drawable.ic_index_sport;
83 | } else if (indexName.contains("逛街")) {
84 | colorResourceId = R.drawable.ic_index_shopping;
85 | } else if (indexName.contains("晾晒")) {
86 | colorResourceId = R.drawable.ic_index_sun_cure;
87 | } else if (indexName.contains("洗车")) {
88 | colorResourceId = R.drawable.ic_index_car_wash;
89 | } else if (indexName.contains("感冒")) {
90 | colorResourceId = R.drawable.ic_index_clod;
91 | } else if (indexName.contains("广场舞")) {
92 | colorResourceId = R.drawable.ic_index_dance;
93 | }
94 | return context.getResources().getDrawable(colorResourceId);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/drawer/CityManagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home.drawer;
2 |
3 | import androidx.recyclerview.widget.RecyclerView;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.AdapterView;
8 | import android.widget.ImageButton;
9 | import android.widget.TextView;
10 |
11 | import com.baronzhang.android.weather.base.BaseRecyclerViewAdapter;
12 | import com.baronzhang.android.library.util.DateConvertUtils;
13 | import com.baronzhang.android.weather.R;
14 | import com.baronzhang.android.weather.data.db.entities.minimalist.Weather;
15 |
16 | import java.util.List;
17 |
18 | import butterknife.BindView;
19 | import butterknife.ButterKnife;
20 |
21 | /**
22 | * 城市管理页面Adapter
23 | *
24 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
25 | * 16/3/16
26 | */
27 | public class CityManagerAdapter extends BaseRecyclerViewAdapter {
28 |
29 | private final List weatherList;
30 |
31 | public CityManagerAdapter(List weatherList) {
32 | this.weatherList = weatherList;
33 | }
34 |
35 | @Override
36 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
37 | View itemView = LayoutInflater.from(parent.getContext())
38 | .inflate(R.layout.item_city_manager, parent, false);
39 | return new ViewHolder(itemView, this);
40 | }
41 |
42 | @Override
43 | public void onBindViewHolder(final ViewHolder holder, int position) {
44 | Weather weather = weatherList.get(position);
45 | holder.city.setText(weather.getCityName());
46 | holder.weather.setText(weather.getWeatherLive().getWeather());
47 | holder.temp.setText(new StringBuilder().append(weather.getWeatherForecasts().get(0).getTempMin()).append("~").append(weather.getWeatherForecasts().get(0).getTempMax()).append("℃").toString());
48 | holder.publishTime.setText("发布于 " + DateConvertUtils.timeStampToDate(weather.getWeatherLive().getTime(), DateConvertUtils.DATA_FORMAT_PATTEN_YYYY_MM_DD_HH_MM));
49 | holder.deleteButton.setOnClickListener(v -> {
50 | Weather removeWeather = weatherList.get(holder.getAdapterPosition());
51 | weatherList.remove(removeWeather);
52 | notifyItemRemoved(holder.getAdapterPosition());
53 |
54 | if (onItemClickListener != null && onItemClickListener instanceof OnCityManagerItemClickListener) {
55 | ((OnCityManagerItemClickListener) onItemClickListener).onDeleteClick(removeWeather.getCityId());
56 | }
57 | });
58 | }
59 |
60 | @Override
61 | public int getItemCount() {
62 | return weatherList == null ? 0 : weatherList.size();
63 | }
64 |
65 | static class ViewHolder extends RecyclerView.ViewHolder {
66 |
67 | @BindView(R.id.item_delete)
68 | ImageButton deleteButton;
69 | @BindView(R.id.item_tv_city)
70 | TextView city;
71 | @BindView(R.id.item_tv_publish_time)
72 | TextView publishTime;
73 | @BindView(R.id.item_tv_weather)
74 | TextView weather;
75 | @BindView(R.id.item_tv_temp)
76 | TextView temp;
77 |
78 | ViewHolder(View itemView, CityManagerAdapter adapter) {
79 | super(itemView);
80 | ButterKnife.bind(this, itemView);
81 | itemView.setOnClickListener(v -> adapter.onItemHolderClick(ViewHolder.this));
82 | }
83 | }
84 |
85 | public interface OnCityManagerItemClickListener extends AdapterView.OnItemClickListener {
86 |
87 | void onDeleteClick(String cityId);
88 | }
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/drawer/DrawerContract.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home.drawer;
2 |
3 | import com.baronzhang.android.weather.base.BasePresenter;
4 | import com.baronzhang.android.weather.base.BaseView;
5 | import com.baronzhang.android.weather.data.db.entities.minimalist.Weather;
6 |
7 | import java.io.InvalidClassException;
8 | import java.util.List;
9 |
10 | /**
11 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
12 | * 16/4/16
13 | */
14 | public interface DrawerContract {
15 |
16 | interface View extends BaseView {
17 |
18 | void displaySavedCities(List weatherList);
19 | }
20 |
21 | interface Presenter extends BasePresenter {
22 |
23 | void loadSavedCities();
24 |
25 | void deleteCity(String cityId);
26 |
27 | void saveCurrentCityToPreference(String cityId) throws InvalidClassException;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/drawer/DrawerMenuModule.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home.drawer;
2 |
3 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
4 | import com.baronzhang.android.weather.feature.home.drawer.DrawerContract;
5 |
6 | import dagger.Module;
7 | import dagger.Provides;
8 |
9 | /**
10 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
11 | * 2016/11/30
12 | */
13 | @Module
14 | public class DrawerMenuModule {
15 |
16 | private DrawerContract.View view;
17 |
18 | public DrawerMenuModule(DrawerContract.View view) {
19 | this.view = view;
20 | }
21 |
22 | @Provides
23 | @ActivityScoped
24 | DrawerContract.View provideCityManagerContactView() {
25 | return view;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/home/drawer/DrawerMenuPresenter.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.home.drawer;
2 |
3 | import android.content.Context;
4 |
5 | import com.baronzhang.android.weather.data.db.dao.WeatherDao;
6 | import com.baronzhang.android.weather.data.db.entities.minimalist.Weather;
7 | import com.baronzhang.android.weather.data.preference.PreferenceHelper;
8 | import com.baronzhang.android.weather.data.preference.WeatherSettings;
9 | import com.baronzhang.android.weather.di.component.DaggerPresenterComponent;
10 | import com.baronzhang.android.weather.di.module.ApplicationModule;
11 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
12 |
13 | import java.io.InvalidClassException;
14 | import java.sql.SQLException;
15 | import java.util.List;
16 |
17 | import javax.inject.Inject;
18 |
19 | import rx.Observable;
20 | import rx.Subscription;
21 | import rx.android.schedulers.AndroidSchedulers;
22 | import rx.schedulers.Schedulers;
23 | import rx.subscriptions.CompositeSubscription;
24 |
25 | /**
26 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
27 | * 16/4/16
28 | */
29 | @ActivityScoped
30 | public final class DrawerMenuPresenter implements DrawerContract.Presenter {
31 |
32 | private DrawerContract.View view;
33 |
34 |
35 | private CompositeSubscription subscriptions;
36 |
37 | @Inject
38 | WeatherDao weatherDao;
39 |
40 | @Inject
41 | public DrawerMenuPresenter(Context context, DrawerContract.View view) {
42 |
43 | this.view = view;
44 | this.subscriptions = new CompositeSubscription();
45 | view.setPresenter(this);
46 |
47 | DaggerPresenterComponent.builder()
48 | .applicationModule(new ApplicationModule(context))
49 | .build().inject(this);
50 | }
51 |
52 | @Override
53 | public void subscribe() {
54 | loadSavedCities();
55 | }
56 |
57 | @Override
58 | public void unSubscribe() {
59 | subscriptions.clear();
60 | }
61 |
62 | @Override
63 | public void loadSavedCities() {
64 |
65 | try {
66 | Subscription subscription = Observable.just(weatherDao.queryAllSaveCity())
67 | .subscribeOn(Schedulers.io())
68 | .observeOn(AndroidSchedulers.mainThread())
69 | .subscribe(weathers -> view.displaySavedCities(weathers));
70 | subscriptions.add(subscription);
71 | } catch (SQLException e) {
72 | e.printStackTrace();
73 | }
74 |
75 | }
76 |
77 | @Override
78 | public void deleteCity(String cityId) {
79 |
80 | Observable.just(deleteCityFromDBAndReturnCurrentCityId(cityId))
81 | .subscribeOn(Schedulers.io())
82 | .observeOn(AndroidSchedulers.mainThread())
83 | .subscribe(currentCityId -> {
84 | if (currentCityId == null)
85 | return;
86 | try {
87 | PreferenceHelper.savePreference(WeatherSettings.SETTINGS_CURRENT_CITY_ID, currentCityId);
88 | } catch (InvalidClassException e) {
89 | e.printStackTrace();
90 | }
91 | });
92 | }
93 |
94 | @Override
95 | public void saveCurrentCityToPreference(String cityId) throws InvalidClassException{
96 | PreferenceHelper.savePreference(WeatherSettings.SETTINGS_CURRENT_CITY_ID, cityId);
97 | }
98 |
99 | private String deleteCityFromDBAndReturnCurrentCityId(String cityId) {
100 | String currentCityId = PreferenceHelper.getSharedPreferences().getString(WeatherSettings.SETTINGS_CURRENT_CITY_ID.getId(), "");
101 | try {
102 | weatherDao.deleteById(cityId);
103 | if (cityId.equals(currentCityId)) {//说明删除的是当前选择的城市,所以需要重新设置默认城市
104 | List weatherList = weatherDao.queryAllSaveCity();
105 | if (weatherList != null && weatherList.size() > 0) {
106 | currentCityId = weatherList.get(0).getCityId();
107 | }
108 | }
109 | } catch (SQLException e) {
110 | e.printStackTrace();
111 | }
112 | return currentCityId;
113 | }
114 |
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/selectcity/SelectCityActivity.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.selectcity;
2 |
3 | import android.os.Bundle;
4 | import androidx.core.view.MenuItemCompat;
5 | import androidx.appcompat.widget.SearchView;
6 | import androidx.appcompat.widget.Toolbar;
7 | import android.view.Menu;
8 | import android.view.MenuItem;
9 |
10 | import com.baronzhang.android.weather.base.BaseActivity;
11 | import com.baronzhang.android.library.util.ActivityUtils;
12 | import com.baronzhang.android.weather.R;
13 | import com.baronzhang.android.weather.WeatherApplication;
14 | import com.jakewharton.rxbinding.support.v7.widget.RxSearchView;
15 |
16 | import java.util.concurrent.TimeUnit;
17 |
18 | import javax.inject.Inject;
19 |
20 | import butterknife.BindView;
21 | import butterknife.ButterKnife;
22 | import rx.android.schedulers.AndroidSchedulers;
23 |
24 | /**
25 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com ==>> baronzhang.com)
26 | */
27 | public class SelectCityActivity extends BaseActivity {
28 |
29 | @BindView(R.id.toolbar)
30 | Toolbar toolbar;
31 |
32 | SelectCityFragment selectCityFragment;
33 |
34 | @Inject
35 | SelectCityPresenter selectCityPresenter;
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_select_city);
41 | ButterKnife.bind(this);
42 |
43 | setSupportActionBar(toolbar);
44 | if (getSupportActionBar() != null) {
45 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
46 | getSupportActionBar().setDisplayShowHomeEnabled(true);
47 | }
48 | selectCityFragment = (SelectCityFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container);
49 | if (selectCityFragment == null) {
50 | selectCityFragment = SelectCityFragment.newInstance();
51 | ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), selectCityFragment, R.id.fragment_container);
52 | }
53 |
54 | DaggerSelectCityComponent.builder()
55 | .applicationComponent(WeatherApplication.getInstance().getApplicationComponent())
56 | .selectCityModule(new SelectCityModule(selectCityFragment))
57 | .build().inject(this);
58 | }
59 |
60 | @Override
61 | public boolean onCreateOptionsMenu(Menu menu) {
62 | getMenuInflater().inflate(R.menu.search_city, menu);
63 | return super.onCreateOptionsMenu(menu);
64 | }
65 |
66 | @Override
67 | public boolean onOptionsItemSelected(MenuItem item) {
68 | int id = item.getItemId();
69 | if (id == R.id.action_search) {
70 | SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
71 | RxSearchView.queryTextChanges(searchView)
72 | .map(charSequence -> charSequence == null ? null : charSequence.toString().trim())
73 | .throttleLast(100, TimeUnit.MILLISECONDS)
74 | .debounce(100, TimeUnit.MILLISECONDS)
75 | .observeOn(AndroidSchedulers.mainThread())
76 | .subscribe(searchText -> selectCityFragment.cityListAdapter.getFilter().filter(searchText));
77 | return true;
78 | }
79 | return super.onOptionsItemSelected(item);
80 | }
81 |
82 |
83 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/selectcity/SelectCityComponent.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.selectcity;
2 |
3 | import com.baronzhang.android.weather.di.component.ApplicationComponent;
4 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
5 |
6 | import dagger.Component;
7 |
8 | /**
9 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
10 | * 2016/11/30
11 | */
12 | @ActivityScoped
13 | @Component(modules = SelectCityModule.class, dependencies = ApplicationComponent.class)
14 | public interface SelectCityComponent {
15 |
16 | void inject(SelectCityActivity selectCityActivity);
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/selectcity/SelectCityContract.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.selectcity;
2 |
3 | import java.util.List;
4 |
5 | import com.baronzhang.android.weather.data.db.entities.City;
6 | import com.baronzhang.android.weather.base.BasePresenter;
7 | import com.baronzhang.android.weather.base.BaseView;
8 |
9 | /**
10 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
11 | */
12 | public interface SelectCityContract {
13 |
14 | interface View extends BaseView {
15 |
16 | void displayCities(List cities);
17 | }
18 |
19 | interface Presenter extends BasePresenter {
20 |
21 | void loadCities();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/selectcity/SelectCityFragment.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.selectcity;
2 |
3 | import android.os.Bundle;
4 | import androidx.recyclerview.widget.DefaultItemAnimator;
5 | import androidx.recyclerview.widget.LinearLayoutManager;
6 | import androidx.recyclerview.widget.RecyclerView;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.Toast;
11 |
12 | import com.baronzhang.android.weather.base.BaseFragment;
13 | import com.baronzhang.android.weather.R;
14 | import com.baronzhang.android.weather.data.db.entities.City;
15 | import com.baronzhang.android.weather.data.preference.PreferenceHelper;
16 | import com.baronzhang.android.weather.data.preference.WeatherSettings;
17 | import com.baronzhang.android.library.view.DividerItemDecoration;
18 |
19 | import java.io.InvalidClassException;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | import butterknife.BindView;
24 | import butterknife.ButterKnife;
25 | import butterknife.Unbinder;
26 |
27 | /**
28 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
29 | */
30 | public class SelectCityFragment extends BaseFragment implements SelectCityContract.View {
31 |
32 | public List cities;
33 | public CityListAdapter cityListAdapter;
34 |
35 | @BindView(R.id.rv_city_list)
36 | RecyclerView recyclerView;
37 | private Unbinder unbinder;
38 |
39 | private SelectCityContract.Presenter presenter;
40 |
41 | public SelectCityFragment() {
42 | }
43 |
44 | public static SelectCityFragment newInstance() {
45 | return new SelectCityFragment();
46 | }
47 |
48 | @Override
49 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
50 | View rootView = inflater.inflate(R.layout.fragment_select_city, container, false);
51 | unbinder = ButterKnife.bind(this, rootView);
52 |
53 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
54 | recyclerView.setLayoutManager(linearLayoutManager);
55 | recyclerView.setItemAnimator(new DefaultItemAnimator());
56 | recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
57 |
58 | cities = new ArrayList<>();
59 | cityListAdapter = new CityListAdapter(cities);
60 | cityListAdapter.setOnItemClickListener((parent, view, position, id) -> {
61 | try {
62 | City selectedCity = cityListAdapter.mFilterData.get(position);
63 | PreferenceHelper.savePreference(WeatherSettings.SETTINGS_CURRENT_CITY_ID, selectedCity.getCityId() + "");
64 | Toast.makeText(this.getActivity(), selectedCity.getCityName(), Toast.LENGTH_LONG).show();
65 | getActivity().finish();
66 | } catch (InvalidClassException e) {
67 | e.printStackTrace();
68 | }
69 | });
70 | recyclerView.setAdapter(cityListAdapter);
71 | presenter.subscribe();
72 | return rootView;
73 | }
74 |
75 |
76 | @Override
77 | public void onDestroyView() {
78 | super.onDestroyView();
79 | unbinder.unbind();
80 | presenter.unSubscribe();
81 | }
82 |
83 |
84 | @Override
85 | public void displayCities(List cities) {
86 | this.cities.addAll(cities);
87 | cityListAdapter.notifyDataSetChanged();
88 | }
89 |
90 | @Override
91 | public void setPresenter(SelectCityContract.Presenter presenter) {
92 | this.presenter = presenter;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/selectcity/SelectCityModule.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.selectcity;
2 |
3 | import dagger.Module;
4 | import dagger.Provides;
5 |
6 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
7 |
8 | /**
9 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
10 | * 2016/11/30
11 | */
12 | @Module
13 | public class SelectCityModule {
14 |
15 | private SelectCityContract.View view;
16 |
17 | public SelectCityModule(SelectCityContract.View view) {
18 | this.view = view;
19 | }
20 |
21 | @Provides
22 | @ActivityScoped
23 | SelectCityContract.View provideSelectCityContractView() {
24 | return view;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/feature/selectcity/SelectCityPresenter.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.feature.selectcity;
2 |
3 | import android.content.Context;
4 |
5 | import com.baronzhang.android.weather.data.db.dao.CityDao;
6 | import com.baronzhang.android.weather.di.component.DaggerPresenterComponent;
7 | import com.baronzhang.android.weather.di.module.ApplicationModule;
8 | import com.baronzhang.android.weather.di.scope.ActivityScoped;
9 |
10 | import javax.inject.Inject;
11 |
12 | import rx.Observable;
13 | import rx.Subscription;
14 | import rx.android.schedulers.AndroidSchedulers;
15 | import rx.schedulers.Schedulers;
16 | import rx.subscriptions.CompositeSubscription;
17 |
18 | /**
19 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
20 | */
21 | @ActivityScoped
22 | public final class SelectCityPresenter implements SelectCityContract.Presenter {
23 |
24 | private final SelectCityContract.View cityListView;
25 |
26 | private CompositeSubscription subscriptions;
27 |
28 | @Inject
29 | CityDao cityDao;
30 |
31 | @Inject
32 | SelectCityPresenter(Context context, SelectCityContract.View view) {
33 |
34 | this.cityListView = view;
35 | this.subscriptions = new CompositeSubscription();
36 | cityListView.setPresenter(this);
37 |
38 | DaggerPresenterComponent.builder()
39 | .applicationModule(new ApplicationModule(context))
40 | .build().inject(this);
41 | }
42 |
43 | @Override
44 | public void loadCities() {
45 | Subscription subscription = Observable.just(cityDao.queryCityList())
46 | .subscribeOn(Schedulers.io())
47 | .observeOn(AndroidSchedulers.mainThread())
48 | .subscribe(cityListView::displayCities);
49 | subscriptions.add(subscription);
50 | }
51 |
52 | @Override
53 | public void subscribe() {
54 | loadCities();
55 | }
56 |
57 | @Override
58 | public void unSubscribe() {
59 | subscriptions.clear();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/util/StethoHelper.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.util;
2 |
3 | import android.content.Context;
4 |
5 | import okhttp3.OkHttpClient;
6 |
7 | /**
8 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
9 | * 2017/7/25
10 | */
11 | public interface StethoHelper {
12 |
13 | void init(Context context);
14 |
15 | OkHttpClient.Builder addNetworkInterceptor(OkHttpClient.Builder builder);
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baronzhang/android/weather/util/stetho/ReleaseStethoHelper.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.weather.util.stetho;
2 |
3 | import android.content.Context;
4 |
5 | import com.baronzhang.android.weather.util.StethoHelper;
6 |
7 | import okhttp3.OkHttpClient;
8 |
9 | /**
10 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
11 | * 2017/7/25
12 | */
13 | public class ReleaseStethoHelper implements StethoHelper {
14 |
15 | @Override
16 | public void init(Context context) {
17 |
18 | }
19 |
20 | @Override
21 | public OkHttpClient.Builder addNetworkInterceptor(OkHttpClient.Builder builder) {
22 | return null;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_camera.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_gallery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_manage.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_send.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_slideshow.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/drawable-xhdpi/ic_menu_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/drawable-xxhdpi/ic_menu_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/weather_bg_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/drawable-xxhdpi/weather_bg_1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/weather_bg_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/drawable-xxhdpi/weather_bg_2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_launch_window.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_index_car_wash.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_index_clod.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_index_dress.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_index_shopping.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_index_sport.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_index_sun_cure.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_index_sunscreen.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
27 |
30 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_vector_weather.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_vector_weather2.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_card_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-v21/item_city_manager.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
18 |
19 |
26 |
27 |
35 |
36 |
43 |
44 |
53 |
54 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_city_manager.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_select_city.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_welcome.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_drawer_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_select_city.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_city.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_city_manager.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
17 |
18 |
24 |
25 |
32 |
33 |
41 |
42 |
49 |
50 |
59 |
60 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
26 |
27 |
35 |
36 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_forecast.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
29 |
30 |
39 |
40 |
52 |
53 |
63 |
64 |
73 |
74 |
84 |
85 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_life_index.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
26 |
27 |
36 |
37 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_app_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_drawer_menu_head.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
20 |
21 |
28 |
29 |
39 |
40 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
14 |
15 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/search_city.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/city.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/app/src/main/res/raw/city.db
--------------------------------------------------------------------------------
/app/src/main/res/values-v19/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v23/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #00AD7C
4 | @color/colorPrimary
5 | #FA4659
6 |
7 | @color/colorPrimary
8 |
9 | #E6E6E6
10 |
11 | @android:color/darker_gray
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 | 16dp
7 | 160dp
8 | 16dp
9 | 16dp
10 |
11 | 24sp
12 | 22sp
13 | 20sp
14 | 18sp
15 | 16sp
16 | 14sp
17 | 12sp
18 | 10sp
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 | - @android:drawable/ic_menu_camera
3 | - @android:drawable/ic_menu_gallery
4 | - @android:drawable/ic_menu_slideshow
5 | - @android:drawable/ic_menu_manage
6 | - @android:drawable/ic_menu_share
7 | - @android:drawable/ic_menu_send
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 天气
3 | baron.zhanglei@gmail.com
4 | http://baronzhang.com
5 | 城市选择
6 | 城市管理
7 | @string/action_fabric_test
8 |
9 | 打开抽屉
10 | 关闭抽屉
11 |
12 | 设置
13 | 关于
14 | 反馈
15 | Fabric Test
16 | 正在导入城市数据…
17 |
18 | 图片描述
19 |
20 |
21 | "发布时间 "
22 |
23 | 详情
24 | 预报
25 | 污染指数
26 | 生活指数
27 | /
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | apply from: "dependencies.gradle"
3 |
4 | buildscript {
5 | repositories {
6 | jcenter()
7 | google()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.6.3'
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 |
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | jcenter()
20 | maven { url 'https://jitpack.io' }
21 | google()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/dependencies.gradle:
--------------------------------------------------------------------------------
1 | //def supportVersion = "28.0.0"
2 | def rxBindingVersion = "0.4.0"
3 | def retrofitVersion = "2.5.0"
4 | def okHttpVersion = "3.14.0"
5 | def stethoVersion = "1.5.0"
6 | def butterKnifeVersion = "10.1.0"
7 | def daggerVersion = "2.8"
8 | def ormLiteVersion = "4.48"
9 | def fastJsonVersion = "1.1.60.android"
10 |
11 | project.ext {
12 | android = [
13 | compileSdkVersion: 28,
14 | applicationId : "com.baronzhang.android.weather",
15 | minSdkVersion : 19,
16 | targetSdkVersion : 28,
17 | versionCode : 1,
18 | versionName : "1.0"
19 | ]
20 |
21 | dependencies = [
22 | //android-support
23 | // "support-v4" : "com.android.support:support-v4:${supportVersion}",
24 | // "appcompat-v7" : "com.android.support:appcompat-v7:${supportVersion}",
25 | // "design" : "com.android.support:design:${supportVersion}",
26 | // "recyclerview" : "com.android.support:recyclerview-v7:${supportVersion}",
27 | // "cardview" : "com.android.support:cardview-v7:${supportVersion}",
28 |
29 | "support-v4" : "androidx.legacy:legacy-support-v4:1.0.0",
30 | "appcompat-v7" : "androidx.appcompat:appcompat:1.0.0",
31 | "design" : "com.google.android.material:material:1.0.0-rc01",
32 | "recyclerview" : "androidx.recyclerview:recyclerview:1.0.0",
33 | "cardview" : "androidx.cardview:cardview:1.0.0",
34 |
35 | //java8-support
36 | "stream" : "com.annimon:stream:1.0.8",
37 |
38 | //rx
39 | "rxandroid" : "io.reactivex:rxandroid:1.2.1",
40 | "rxbinding" : "com.jakewharton.rxbinding:rxbinding:${rxBindingVersion}",
41 | "rxbinding-support-v4" : "com.jakewharton.rxbinding:rxbinding-support-v4:${rxBindingVersion}",
42 | "rxbinding-appcompat-v7" : "com.jakewharton.rxbinding:rxbinding-appcompat-v7:${rxBindingVersion}",
43 | "rxbinding-design" : "com.jakewharton.rxbinding:rxbinding-design:${rxBindingVersion}",
44 | "rxbinding-recyclerview-v7" : "com.jakewharton.rxbinding:rxbinding-recyclerview-v7:${rxBindingVersion}",
45 |
46 | //retrofit
47 | "retrofit" : "com.squareup.retrofit2:retrofit:${retrofitVersion}",
48 | "adapter-rxjava" : "com.squareup.retrofit2:adapter-rxjava:${retrofitVersion}",
49 |
50 | //dagger
51 | "dagger" : "com.google.dagger:dagger:${daggerVersion}",
52 | "dagger-compiler" : "com.google.dagger:dagger-compiler:${daggerVersion}",
53 |
54 | //facebook
55 | "stetho" : "com.facebook.stetho:stetho:${stethoVersion}",
56 | "stetho-okhttp3" : "com.facebook.stetho:stetho-okhttp3:${stethoVersion}",
57 |
58 | //others
59 | "okhttp3-logging-interceptor" : "com.squareup.okhttp3:logging-interceptor:${okHttpVersion}",
60 | "ormlite-android" : "com.j256.ormlite:ormlite-android:${ormLiteVersion}",
61 | "fastjson" : "com.alibaba:fastjson:${fastJsonVersion}",
62 | "butterknife" : "com.jakewharton:butterknife:${butterKnifeVersion}",
63 | "butterknife-compiler" : "com.jakewharton:butterknife-compiler:${butterKnifeVersion}",
64 | "retrofit2-fastjson-converter": "com.github.BaronZ88:Retrofit2-FastJson-Converter:1.2",
65 | "SmartRefreshLayout" : "com.scwang.smartrefresh:SmartRefreshLayout:1.0.3",
66 | "SmartRefreshHeader" : "com.scwang.smartrefresh:SmartRefreshHeader:1.0.3"
67 | ]
68 | }
--------------------------------------------------------------------------------
/framework_minimalist_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/framework_minimalist_weather.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## For more details on how to configure your build environment visit
2 | # http://www.gradle.org/docs/current/userguide/build_environment.html
3 | #
4 | # Specifies the JVM arguments used for the daemon process.
5 | # The setting is particularly useful for tweaking memory settings.
6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8 | #
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #Wed Apr 29 01:18:35 CST 2020
14 | android.enableJetifier=true
15 | org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx1536M"
16 | android.useAndroidX=true
17 | android.enableBuildCache=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Apr 28 02:17:57 CST 2020
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-5.6.4-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 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.android.compileSdkVersion
5 | defaultConfig {
6 | minSdkVersion rootProject.ext.android.minSdkVersion
7 | targetSdkVersion rootProject.ext.android.targetSdkVersion
8 | versionCode 1
9 | versionName "1.0"
10 | }
11 | buildTypes {
12 | release {
13 | minifyEnabled false
14 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
15 | }
16 | }
17 |
18 | compileOptions {
19 | sourceCompatibility JavaVersion.VERSION_1_8
20 | targetCompatibility JavaVersion.VERSION_1_8
21 | }
22 |
23 | lintOptions {
24 | abortOnError false
25 | }
26 |
27 | publishNonDefault true
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(dir: 'libs', include: ['*.jar'])
32 | testImplementation 'junit:junit:4.12'
33 | api rootProject.ext.dependencies["support-v4"]
34 | api rootProject.ext.dependencies["appcompat-v7"]
35 | api rootProject.ext.dependencies["design"]
36 | api rootProject.ext.dependencies["recyclerview"]
37 | api rootProject.ext.dependencies["cardview"]
38 | api rootProject.ext.dependencies["rxandroid"]
39 | api rootProject.ext.dependencies["rxbinding"]
40 | api rootProject.ext.dependencies["rxbinding-support-v4"]
41 | api rootProject.ext.dependencies["rxbinding-appcompat-v7"]
42 | api rootProject.ext.dependencies["rxbinding-design"]
43 | api rootProject.ext.dependencies["rxbinding-recyclerview-v7"]
44 | api rootProject.ext.dependencies["ormlite-android"]
45 | api rootProject.ext.dependencies["stream"]
46 | api rootProject.ext.dependencies["retrofit"]
47 | api rootProject.ext.dependencies["adapter-rxjava"]
48 | api rootProject.ext.dependencies["fastjson"]
49 | api rootProject.ext.dependencies["okhttp3-logging-interceptor"]
50 |
51 | debugApi rootProject.ext.dependencies["stetho"]
52 | debugApi rootProject.ext.dependencies["stetho-okhttp3"]
53 |
54 | api rootProject.ext.dependencies["SmartRefreshLayout"]
55 | api rootProject.ext.dependencies["SmartRefreshHeader"]
56 |
57 | api 'org.glassfish:javax.annotation:10.0-b28'
58 | }
59 |
--------------------------------------------------------------------------------
/library/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/baron/develop/android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | #ButterKnife混淆配置
20 | -keep class butterknife.** { *; }
21 | -dontwarn butterknife.internal.**
22 | -keep class **$$ViewBinder { *; }
23 |
24 | -keepclasseswithmembernames class * {
25 | @butterknife.* ;
26 | }
27 |
28 | -keepclasseswithmembernames class * {
29 | @butterknife.* ;
30 | }
31 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/ActivityUtils.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util;
2 |
3 |
4 | import androidx.fragment.app.Fragment;
5 | import androidx.fragment.app.FragmentManager;
6 | import androidx.fragment.app.FragmentTransaction;
7 |
8 | /**
9 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
10 | * 16/4/13
11 | */
12 | public final class ActivityUtils {
13 |
14 | public static void addFragmentToActivity(FragmentManager fragmentManager, Fragment fragment, int frameId) {
15 | FragmentTransaction transaction = fragmentManager.beginTransaction();
16 | transaction.add(frameId, fragment);
17 | transaction.commit();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/DateConvertUtils.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 | import java.util.Locale;
8 |
9 | /**
10 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
11 | * 2016/12/12
12 | */
13 | public final class DateConvertUtils {
14 |
15 | public static final String DATA_FORMAT_PATTEN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
16 | public static final String DATA_FORMAT_PATTEN_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
17 | public static final String DATA_FORMAT_PATTEN_YYYY_MM_DD = "yyyy-MM-dd";
18 |
19 | /**
20 | * 将时间转换为时间戳
21 | *
22 | * @param data 待转换的日期
23 | * @param dataFormatPatten 待转换日期格式
24 | */
25 | public static long dateToTimeStamp(String data, String dataFormatPatten) {
26 |
27 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dataFormatPatten, Locale.CHINA);
28 | Date date = null;
29 | try {
30 | date = simpleDateFormat.parse(data);
31 | } catch (ParseException e) {
32 | e.printStackTrace();
33 | }
34 | assert date != null;
35 | return date.getTime();
36 | }
37 |
38 | /**
39 | * 将时间戳转换为日期
40 | *
41 | * @param time 待转换的时间戳
42 | * @param dataFormatPatten 转换出的日期格式
43 | */
44 | public static String timeStampToDate(long time, String dataFormatPatten) {
45 |
46 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dataFormatPatten, Locale.CHINA);
47 | Date date = new Date(time);
48 | return simpleDateFormat.format(date);
49 | }
50 |
51 | /**
52 | * 日期转星期
53 | *
54 | * @param dateString 日期
55 | * @return 周一 周二 周三 ...
56 | */
57 | public static String convertDataToWeek(String dateString) {
58 |
59 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATA_FORMAT_PATTEN_YYYY_MM_DD, Locale.CHINA);
60 | Date date = null;
61 | try {
62 | date = simpleDateFormat.parse(dateString);
63 | } catch (ParseException e) {
64 | e.printStackTrace();
65 | }
66 | if (isNow(date))
67 | return "今天";
68 |
69 | String[] weekDaysName = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
70 | Calendar calendar = Calendar.getInstance();
71 | calendar.setTime(date);
72 | int intWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
73 | return weekDaysName[intWeek];
74 | }
75 |
76 | /**
77 | * 日期转换
78 | *
79 | * @return 08.07
80 | */
81 | public static String convertDataToString(String dateString) {
82 |
83 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATA_FORMAT_PATTEN_YYYY_MM_DD, Locale.CHINA);
84 | Date date = null;
85 | try {
86 | date = simpleDateFormat.parse(dateString);
87 | } catch (ParseException e) {
88 | e.printStackTrace();
89 | }
90 | if (date == null)
91 | return "";
92 | return (String.valueOf(date.getMonth()).length() == 1 ? "0" + date.getMonth() : String.valueOf(date.getMonth()))
93 | + "." + (String.valueOf(date.getDay()).length() == 1 ? "0" + date.getDay() : String.valueOf(date.getDay()));
94 | }
95 |
96 | /**
97 | * 判断时间是不是今天
98 | *
99 | * @return 是返回true,不是返回false
100 | */
101 | private static boolean isNow(Date date) {
102 | //当前时间
103 | Date now = new Date();
104 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATA_FORMAT_PATTEN_YYYY_MM_DD, Locale.CHINA);
105 | //获取今天的日期
106 | String nowDay = simpleDateFormat.format(now);
107 | //对比的时间
108 | String day = simpleDateFormat.format(date);
109 | return day.equals(nowDay);
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/NetworkUtils.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | /**
8 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
9 | */
10 | public final class NetworkUtils {
11 |
12 | /**
13 | * 判断网络连接是否可用
14 | */
15 | public static Boolean isNetworkConnected(Context context) {
16 | ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
17 | if (manager != null) {
18 | NetworkInfo networkinfo = manager.getActiveNetworkInfo();
19 | if (networkinfo != null && networkinfo.isConnected() && networkinfo.isAvailable()) {
20 | return true;
21 | }
22 | }
23 | return false;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/RxSchedulerUtils.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util;
2 |
3 |
4 | import rx.Observable;
5 | import rx.android.schedulers.AndroidSchedulers;
6 | import rx.schedulers.Schedulers;
7 |
8 |
9 | /**
10 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
11 | * 2017/2/17
12 | */
13 | public final class RxSchedulerUtils {
14 |
15 | /**
16 | * 在RxJava的使用过程中我们会频繁的调用subscribeOn()和observeOn(),通过Transformer结合
17 | * Observable.compose()我们可以复用这些代码
18 | *
19 | * @return Transformer
20 | */
21 | public static Observable.Transformer normalSchedulersTransformer() {
22 |
23 | return observable -> observable.subscribeOn(Schedulers.io())
24 | .observeOn(AndroidSchedulers.mainThread());
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/lifecycle/ActivityLifecycleEvent.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util.lifecycle;
2 |
3 | /**
4 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
5 | * 2017/2/17
6 | */
7 | public enum ActivityLifecycleEvent {
8 |
9 | CREATE,
10 | START,
11 | RESUME,
12 | PAUSE,
13 | STOP,
14 | DESTROY,
15 | }
16 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/lifecycle/FragmentLifecycleEvent.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util.lifecycle;
2 |
3 | /**
4 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
5 | * 2017/2/17
6 | */
7 | public enum FragmentLifecycleEvent {
8 |
9 | ATTACH,
10 | CREATE,
11 | CREATE_VIEW,
12 | START,
13 | RESUME,
14 | PAUSE,
15 | STOP,
16 | DESTROY_VIEW,
17 | DESTROY,
18 | DETACH,
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/system/AndroidMHelper.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util.system;
2 |
3 | import android.app.Activity;
4 | import android.os.Build;
5 | import android.view.View;
6 |
7 | /**
8 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
9 | * 2017/6/2
10 | */
11 | class AndroidMHelper implements SystemHelper {
12 |
13 | @Override
14 | public boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark) {
15 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
16 | if (isFontColorDark) {
17 | // 沉浸式
18 | // activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
19 | //非沉浸式
20 | activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
21 | } else {
22 | //非沉浸式
23 | activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
24 | }
25 | return true;
26 | }
27 | return false;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/system/FlymeHelper.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util.system;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 | import android.view.WindowManager;
6 |
7 | import java.lang.reflect.Field;
8 |
9 | /**
10 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
11 | * 2017/6/2
12 | */
13 | class FlymeHelper implements SystemHelper {
14 |
15 | /**
16 | * 设置状态栏图标为深色和魅族特定的文字风格
17 | * 可以用来判断是否为 Flyme 用户
18 | *
19 | * @param isFontColorDark 是否把状态栏字体及图标颜色设置为深色
20 | * @return boolean 成功执行返回 true
21 | */
22 | @Override
23 | public boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark) {
24 | Window window = activity.getWindow();
25 | boolean result = false;
26 | if (window != null) {
27 | try {
28 | WindowManager.LayoutParams lp = window.getAttributes();
29 | Field darkFlag = WindowManager.LayoutParams.class
30 | .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
31 | Field flymeFlags = WindowManager.LayoutParams.class
32 | .getDeclaredField("meizuFlags");
33 | darkFlag.setAccessible(true);
34 | flymeFlags.setAccessible(true);
35 | int bit = darkFlag.getInt(null);
36 | int value = flymeFlags.getInt(lp);
37 | if (isFontColorDark) {
38 | value |= bit;
39 | } else {
40 | value &= ~bit;
41 | }
42 | flymeFlags.setInt(lp, value);
43 | window.setAttributes(lp);
44 | result = true;
45 | } catch (Exception e) {
46 | e.printStackTrace();
47 | }
48 | }
49 | return result;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/system/MIUIHelper.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util.system;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 |
6 | import java.lang.reflect.Field;
7 | import java.lang.reflect.Method;
8 |
9 | /**
10 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
11 | * 2017/6/2
12 | */
13 | class MIUIHelper implements SystemHelper {
14 |
15 | /**
16 | * 设置状态栏字体图标为深色,需要MIUI6以上
17 | *
18 | * @param isFontColorDark 是否把状态栏字体及图标颜色设置为深色
19 | * @return boolean 成功执行返回true
20 | */
21 | @Override
22 | public boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark) {
23 |
24 | Window window = activity.getWindow();
25 | boolean result = false;
26 | if (window != null) {
27 | Class clazz = window.getClass();
28 | try {
29 | int darkModeFlag = 0;
30 | Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
31 | Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
32 | darkModeFlag = field.getInt(layoutParams);
33 | Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
34 | if (isFontColorDark) {
35 | extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
36 | } else {
37 | extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
38 | }
39 | result = true;
40 | } catch (Exception e) {
41 | e.printStackTrace();
42 | }
43 | }
44 | return result;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/system/StatusBarHelper.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util.system;
2 |
3 | import android.app.Activity;
4 | import android.os.Build;
5 | import androidx.annotation.IntDef;
6 |
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.RetentionPolicy;
9 |
10 | /**
11 | * 适配4.4以上版本 MIUI6、Flyme 和其他 Android6.0 及以上版本状态栏字体颜色
12 | *
13 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
14 | * 2017/6/2
15 | */
16 | public class StatusBarHelper {
17 |
18 | private static final int MIUI = 1;
19 | private static final int FLYME = 2;
20 | private static final int ANDROID_M = 3;
21 | private static final int OTHER = 4;
22 |
23 | @IntDef({MIUI, FLYME, ANDROID_M, OTHER})
24 | @Retention(RetentionPolicy.SOURCE)
25 | @interface SystemType {
26 | }
27 |
28 | public static void statusBarLightMode(Activity activity) {
29 | statusMode(activity, true);
30 | }
31 |
32 | public static int statusBarDarkMode(Activity activity) {
33 | return statusMode(activity, false);
34 | }
35 |
36 | private static int statusMode(Activity activity, boolean isFontColorDark) {
37 | @SystemType int result = 0;
38 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
39 | if (new MIUIHelper().setStatusBarLightMode(activity, isFontColorDark)) {
40 | result = MIUI;
41 | } else if (new FlymeHelper().setStatusBarLightMode(activity, isFontColorDark)) {
42 | result = FLYME;
43 | }
44 | // else if (new AndroidMHelper().setStatusBarLightMode(activity, isFontColorDark)) {
45 | // result = ANDROID_M;
46 | // }
47 | }
48 | return result;
49 | }
50 |
51 |
52 | public static void statusBarLightMode(Activity activity, @SystemType int type) {
53 | statusBarMode(activity, type, true);
54 |
55 | }
56 |
57 | public static void statusBarDarkMode(Activity activity, @SystemType int type) {
58 | statusBarMode(activity, type, false);
59 | }
60 |
61 | private static void statusBarMode(Activity activity, @SystemType int type, boolean isFontColorDark) {
62 | if (type == MIUI) {
63 | new MIUIHelper().setStatusBarLightMode(activity, isFontColorDark);
64 | } else if (type == FLYME) {
65 | new FlymeHelper().setStatusBarLightMode(activity, isFontColorDark);
66 | }
67 | // else if (type == ANDROID_M) {
68 | // new AndroidMHelper().setStatusBarLightMode(activity, isFontColorDark);
69 | // }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/util/system/SystemHelper.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.util.system;
2 |
3 | import android.app.Activity;
4 |
5 | /**
6 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
7 | * 2017/6/2
8 | */
9 | interface SystemHelper {
10 |
11 | boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark);
12 | }
13 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/view/DividerItemDecoration.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.view;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Rect;
7 | import android.graphics.drawable.Drawable;
8 | import androidx.recyclerview.widget.LinearLayoutManager;
9 | import androidx.recyclerview.widget.RecyclerView;
10 | import android.view.View;
11 |
12 | /**
13 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
14 | * 16/3/21
15 | */
16 | public class DividerItemDecoration extends RecyclerView.ItemDecoration {
17 |
18 | private static final int[] ATTRS = new int[]{
19 | android.R.attr.listDivider
20 | };
21 |
22 | public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
23 |
24 | public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
25 |
26 | private Drawable mDivider;
27 |
28 | private int mOrientation;
29 |
30 | public DividerItemDecoration(Context context, int orientation) {
31 | final TypedArray a = context.obtainStyledAttributes(ATTRS);
32 | mDivider = a.getDrawable(0);
33 | a.recycle();
34 | setOrientation(orientation);
35 | }
36 |
37 | public void setOrientation(int orientation) {
38 | if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
39 | throw new IllegalArgumentException("invalid orientation");
40 | }
41 | mOrientation = orientation;
42 | }
43 |
44 | @Override
45 | public void onDraw(Canvas c, RecyclerView parent) {
46 |
47 | if (mOrientation == VERTICAL_LIST) {
48 | drawVertical(c, parent);
49 | } else {
50 | drawHorizontal(c, parent);
51 | }
52 |
53 | }
54 |
55 |
56 | public void drawVertical(Canvas c, RecyclerView parent) {
57 | final int left = parent.getPaddingLeft();
58 | final int right = parent.getWidth() - parent.getPaddingRight();
59 |
60 | final int childCount = parent.getChildCount();
61 | for (int i = 0; i < childCount; i++) {
62 | final View child = parent.getChildAt(i);
63 | RecyclerView v = new RecyclerView(parent.getContext());
64 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
65 | .getLayoutParams();
66 | final int top = child.getBottom() + params.bottomMargin;
67 | final int bottom = top + mDivider.getIntrinsicHeight();
68 | mDivider.setBounds(left, top, right, bottom);
69 | mDivider.draw(c);
70 | }
71 | }
72 |
73 | public void drawHorizontal(Canvas c, RecyclerView parent) {
74 | final int top = parent.getPaddingTop();
75 | final int bottom = parent.getHeight() - parent.getPaddingBottom();
76 |
77 | final int childCount = parent.getChildCount();
78 | for (int i = 0; i < childCount; i++) {
79 | final View child = parent.getChildAt(i);
80 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
81 | .getLayoutParams();
82 | final int left = child.getRight() + params.rightMargin;
83 | final int right = left + mDivider.getIntrinsicHeight();
84 | mDivider.setBounds(left, top, right, bottom);
85 | mDivider.draw(c);
86 | }
87 | }
88 |
89 | @Override
90 | public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
91 | if (mOrientation == VERTICAL_LIST) {
92 | outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
93 | } else {
94 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/library/src/main/java/com/baronzhang/android/library/view/OnRecyclerViewItemClickListener.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.library.view;
2 |
3 | /**
4 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
5 | * 16/3/21
6 | */
7 | public interface OnRecyclerViewItemClickListener {
8 |
9 | void onRecyclerViewItemClick(int position);
10 | }
11 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AndroidLibrary
3 |
4 |
5 | Hello blank fragment
6 |
7 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library', ':widget'
2 |
--------------------------------------------------------------------------------
/widget/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/widget/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 |
5 | compileSdkVersion rootProject.ext.android.compileSdkVersion
6 | defaultConfig {
7 | minSdkVersion rootProject.ext.android.minSdkVersion
8 | targetSdkVersion rootProject.ext.android.targetSdkVersion
9 | versionCode 1
10 | versionName "1.0"
11 |
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | vectorDrawables.useSupportLibrary = true
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | }
22 |
23 | dependencies {
24 | implementation fileTree(dir: 'libs', include: ['*.jar'])
25 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0-alpha4', {
26 | exclude group: 'com.android.support', module: 'support-annotations'
27 | })
28 | implementation rootProject.ext.dependencies["support-v4"]
29 | implementation rootProject.ext.dependencies["appcompat-v7"]
30 | testImplementation 'junit:junit:4.12'
31 | }
32 |
--------------------------------------------------------------------------------
/widget/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/baron/develop/android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/widget/src/androidTest/java/com/baronzhang/android/widget/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.widget;
2 |
3 | import android.content.Context;
4 | import androidx.test.InstrumentationRegistry;
5 | import androidx.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.baronzhang.android.widget.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/widget/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/widget/src/main/java/com/baronzhang/android/widget/IndicatorValueChangeListener.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.widget;
2 |
3 | /**
4 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
5 | */
6 | public interface IndicatorValueChangeListener {
7 |
8 | void onChange(int currentIndicatorValue, String stateDescription, int indicatorTextColor);
9 | }
10 |
--------------------------------------------------------------------------------
/widget/src/main/java/com/baronzhang/android/widget/TitleView.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.widget;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import androidx.annotation.Nullable;
6 | import android.util.AttributeSet;
7 | import android.util.DisplayMetrics;
8 | import android.util.TypedValue;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | /**
15 | * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com)
16 | * 2017/8/3
17 | */
18 | public class TitleView extends LinearLayout {
19 |
20 | private int defaultTitleTextSize = 7;// 默认文字大小
21 | private int defaultTitleBackgroundColorId = R.color.default_title_background_color;// 默认背景颜色
22 | private int defaultTitleTextColorId = R.color.default_title_text_color;// 默认文字颜色
23 | private int defaultTitleLineColorId = R.color.default_title_line_color;// 默认底部线条颜色
24 |
25 | private String title;
26 | private int titleTextSize;
27 | private int titleTextColor;
28 | private int titleBackgroundColor;
29 | private int titleLineColor;
30 |
31 | public TitleView(Context context, @Nullable AttributeSet attrs) {
32 | super(context, attrs);
33 |
34 | initAttrs(context, attrs);
35 |
36 | initView();
37 | }
38 |
39 | private void initAttrs(Context context, @Nullable AttributeSet attrs) {
40 |
41 | DisplayMetrics dm = getResources().getDisplayMetrics();
42 | this.defaultTitleTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, defaultTitleTextSize, dm);
43 |
44 | TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleView);
45 | title = typedArray.getString(R.styleable.TitleView_titleViewText);
46 | titleTextSize = typedArray.getDimensionPixelSize(R.styleable.TitleView_titleViewTextSize, defaultTitleTextSize);
47 | titleTextColor = typedArray.getColor(R.styleable.TitleView_titleViewTextColor, getResources().getColor(defaultTitleTextColorId));
48 | titleBackgroundColor = typedArray.getColor(R.styleable.TitleView_titleViewBackground, getResources().getColor(defaultTitleBackgroundColorId));
49 | titleLineColor = typedArray.getColor(R.styleable.TitleView_titleViewLineColor, getResources().getColor(defaultTitleLineColorId));
50 | typedArray.recycle();
51 | }
52 |
53 | private void initView() {
54 |
55 | LayoutInflater.from(getContext()).inflate(R.layout.layout_title_view, this, true);
56 | this.setOrientation(VERTICAL);
57 | this.setBackgroundColor(titleBackgroundColor);
58 |
59 | TextView titleTextView = (TextView) findViewById(R.id.title_text_view);
60 | titleTextView.setText(title);
61 | // titleTextView.setTextSize(titleTextSize);
62 | titleTextView.setTextColor(titleTextColor);
63 |
64 | View view = findViewById(R.id.title_line_view);
65 | view.setBackgroundColor(titleLineColor);
66 | }
67 | }
68 |
69 |
70 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable-xxxhdpi/housekeeper_hotdegree_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/widget/src/main/res/drawable-xxxhdpi/housekeeper_hotdegree_mark.png
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/ic_vector_indicator_down.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/ic_vector_indicator_location.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/widget/src/main/res/layout/layout_title_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/widget/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - 优
6 | - 良
7 | - 轻度污染
8 | - 中度污染
9 | - 重度污染
10 | - 严重污染
11 |
12 |
13 |
14 | - @color/indicator_color_1
15 | - @color/indicator_color_2
16 | - @color/indicator_color_3
17 | - @color/indicator_color_4
18 | - @color/indicator_color_5
19 | - @color/indicator_color_6
20 |
21 |
22 |
--------------------------------------------------------------------------------
/widget/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/widget/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FFFFFF
5 |
6 | #60C2CB
7 | #6FB452
8 | #F2AC00
9 | #DF3000
10 | #CA004A
11 | #7D0000
12 |
13 | #B2FFFFFF
14 | #333333
15 | #E6E6E6
16 |
17 |
--------------------------------------------------------------------------------
/widget/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | widget
3 |
4 |
--------------------------------------------------------------------------------
/widget/src/test/java/com/baronzhang/android/widget/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.baronzhang.android.widget;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/扫码关注.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaronZ88/MinimalistWeather/879abc57e8a1d448b0675affcf936b084b7a7ae4/扫码关注.png
--------------------------------------------------------------------------------