最近学习了MVP,Retrofit2,RxJava2框架,感觉收获颇多,于是决定利用所学知识干一番大事业
549545057729183735.png
ps:对这三种框架还不太清楚的童鞋可以看我之前的博客
传送门:
MVP
Retrofit2
RxJava2
效果图
话不多说,先上图
44383753377195125.jpg 133482160071430163.jpg 270702073363472344.jpg 304578177432096238.jpg
勉勉强强能看过去吧(●ˇ∀ˇ●)
那么最重要的来了
那就是
实现
首先,我这里用的后台api接口是和风天气的接口,完全免费,很实用,大家可以去注册一个
和风天气
这个接口会提供很多天气方面的信息,我们只需要取我们想要的就ok了
dafc1839b30b10d8c75e5ede76c13a00.gif1.先修改一下build.gradle文件,引入依赖
//recyclerview
implementation 'com.android.support:recyclerview-v7:28.+'
//retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
//Rxjava and Retrofit(Retrofit+Rx需要添加的依赖)
implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex:rxjava:1.2.1'
//TextInputLayout
implementation 'com.android.support:design:28.+'
2.看一下后台的数据样式
根据json格式构建我们的bean用于接收数据
由于bean类过长,这里我就不再展示了,有兴趣的朋友可以看我的源码
3.创建Retrofit的api接口,用于写请求数据的方法
public interface DataRequest {
//获取天气数据,baseURL在model类里声明
@GET("now")
Observable<Weather> getNowWeather(@Query("location")String location,@Query("key")String key);
}
4.构建自己的MVP架构
我们先思考一下每层需要做的事情,
view:通过presenter从model层获取到数据并展示到界面上,因此我们构建一个setWeather方法,并传一个location用于告诉model层我们要获取哪里的数据
presenter:连接model和view,因此其中的方法就是model和view方法的集合
model:通过presenter从view层得到要获取哪里的数据,运用Retrofit向后台发出数据请求
工程的图纸有了,下面我们就该盖楼了!
MainContract
public class MainContract {
public interface Presenter{
//获取天气数据
void getWeather(String location);
//设置天气到view上
void setWeather(List<Weather> weathers);
}
public interface View{
//获取数据成功
void getSuccess();
//获取失败
void getFailed();
//把数据显示到view上
void setWeather(List<Weather> weathers);
}
}
MainPresenter(Presenter的具体实现)
public class MainPresenter implements MainContract.Presenter{
private MainRepository mainRepository;
private MainContract.View mainView;
public MainPresenter(MainContract.View mainView) {
mainRepository = new MainRepository(this);
this.mainView = mainView;
}
@Override
public void getWeather(String location) {
mainRepository.getWeather(location);
}
@Override
public void setWeather(List<Weather> weathers) {
mainView.setWeather(weathers);
}
}
MainRepository(请求数据方法的具体实现,其中运用了Retrofit+RxJava)
public class MainRepository {
private final static String KEY = "你自己的key";
private final static String TAG = "MainRepository";
private final static String BASE_URL = "https://free-api.heweather.com/s6/weather/";
private List<Weather> weathers = new ArrayList<>();
private MainContract.Presenter presenter;
public MainRepository(MainContract.Presenter presenter) {
this.presenter = presenter;
}
/**
* 获取天气数据
* @param location 城市
* @return Weather类的数据
*/
public void getWeather(String location){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
DataRequest dataRequest = retrofit.create(DataRequest.class);
dataRequest.getNowWeather(location,KEY)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Weather>() {
@Override
public void onCompleted() {
presenter.setWeather(weathers);
Log.d(TAG, "onCompleted: " + weathers.get(0).getHeWeather6().get(0).getBasic().getLocation());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.getMessage());
}
@Override
public void onNext(Weather weather) {
weathers.add(weather);
Log.d(TAG, "onNext: " + weather.getHeWeather6().get(0).getBasic().getLocation());
}
});
weathers.clear();
}
}
MainActivity(视图层的具体实现,ps:部分代码)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
onClick();
}
public void init(){
presenter = new MainPresenter(this);
editText = findViewById(R.id.et_city);
tAdminArea = findViewById(R.id.t_admin_area);
tCnty = findViewById(R.id.t_cnty);
tCondTxt = findViewById(R.id.t_cond_txt);
tFl = findViewById(R.id.t_fl);
tHum = findViewById(R.id.t_hum);
tLat = findViewById(R.id.t_lat);
tLoc = findViewById(R.id.t_loc);
tLocation = findViewById(R.id.t_location);
tLon = findViewById(R.id.t_lon);
tParentCity = findViewById(R.id.t_parent_city);
tTmp = findViewById(R.id.t_tmp);
tWindDir = findViewById(R.id.t_wind_dir);
tWindSc = findViewById(R.id.t_wind_sc);
tWindSpd = findViewById(R.id.t_wind_spd);
bSearch = findViewById(R.id.b_search);
background = findViewById(R.id.background);
//隐藏标题栏
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.hide();
}
}
public void onClick(){
bSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sCity = editText.getText().toString();
presenter.getWeather(sCity);
Log.d(TAG, "onClick: " + sCity);
//隐藏软键盘
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}
});
//回车键的监听
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_UNSPECIFIED) {
sCity = editText.getText().toString();
presenter.getWeather(sCity);
Log.d(TAG, "onClick: " + sCity);
//隐藏软键盘
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}
return false;
}
});
}
@Override
public void getSuccess() {
Toast.makeText(getApplicationContext(),"获取数据成功",Toast.LENGTH_SHORT).show();
}
@Override
public void getFailed() {
Toast.makeText(getApplicationContext(),"获取数据失败",Toast.LENGTH_SHORT).show();
}
@Override
public void setWeather(List<Weather> weathers) {
tWindSpd.setText("风速: " + weathers.get(0).getHeWeather6().get(0).getNow().getWindSpd() + "公里/小时");
tWindSc.setText("风力: " + weathers.get(0).getHeWeather6().get(0).getNow().getWindSc() + "级");
tWindDir.setText("风向: " + weathers.get(0).getHeWeather6().get(0).getNow().getWindDir());
tTmp.setText("温度: " + weathers.get(0).getHeWeather6().get(0).getNow().getTmp() + "℃");
tParentCity.setText("市: " + weathers.get(0).getHeWeather6().get(0).getBasic().getParentCity());
tLon.setText("经度: " + weathers.get(0).getHeWeather6().get(0).getBasic().getLon());
tLocation.setText("地区: " + weathers.get(0).getHeWeather6().get(0).getBasic().getLocation());
tLat.setText("纬度: " + weathers.get(0).getHeWeather6().get(0).getBasic().getLat());
tHum.setText("相对湿度: " + weathers.get(0).getHeWeather6().get(0).getNow().getHum());
tFl.setText("体感温度: " + weathers.get(0).getHeWeather6().get(0).getNow().getFl() + "℃");
tCondTxt.setText("天气状况: " + weathers.get(0).getHeWeather6().get(0).getNow().getCondTxt());
tCnty.setText("国家: " + weathers.get(0).getHeWeather6().get(0).getBasic().getCnty());
tAdminArea.setText("省: " + weathers.get(0).getHeWeather6().get(0).getBasic().getAdminArea());
addWeatherPhoto();
}
就这样,项目完成了是不是很简单?MVP架构让我们的整个项目都很清晰,Retrofit让我们能够轻松的实现网络请求,Rxjava配合Retrofit使用,整个代码成一条链式,并且可以自如的切换线程,简直太方便了!
4356c5bd92f761c685afb2c1e43def95.gif能看我废话到这里的朋友我真的很感激,作为一个刚刚上路的小白,未来还有更多的路要走,希望能和大家一起进步,感谢大家的观看,上男神!
761589853486643181.jpg最后,附上我的github上的项目地址:
github传送门
网友评论