今天写了一个使用MVP架构模式的网络请求数据的Demo,网络请求的是使用了Retrofit请求
自带了Gson解析,Fresco加载网络图片,使用recyclerview展示数据。首先,先把需要用到的依赖导入
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile 'com.android.support:recyclerview-v7:26.+'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'io.reactivex.rxjava2:rxjava:2.1.6'
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
compile 'com.facebook.fresco:fresco:1.5.0'
先做准备工作,建立一个App,初始化Fresco
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
Fresco.initialize(this);
}
}
不要忘了在清单文件里面配置App,还有不要忘了加网络权限,
main_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.a1106lianxi.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#FF4081">
<TextView
android:id="@+id/tv_f"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="←"
android:textColor="#ffffff"
android:textSize="30sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:paddingLeft="10dp"
android:paddingRight="15dp"
android:text="我的收藏"
android:textColor="#ffffff"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_bian"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:paddingLeft="10dp"
android:paddingRight="15dp"
android:text="编辑"
android:textColor="#ffffff"
android:textSize="15sp" />
</RelativeLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</FrameLayout>
</LinearLayout>
布局写好了再去实现view层的接口,然后MainActivity实现接口,重写接口的方法
public interface IMusicView {
public void showData(List<MusicBean.SongListBean> bean);
}
model创建接口,实现方法
public interface IMusicModel {
public Retrofit getUrl(String path);
}
这里用到了一个拦截器,数据源必须加这个拦截器才能出数据
public class LoggingInterceptor implements Interceptor {
private static final String UA = "User-Agent";
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.addHeader(UA, makeUA())
.build();
return chain.proceed(request);
}
private String makeUA() {
String s = Build.BRAND + "/" + Build.MODEL + "/" + Build.VERSION.RELEASE;
return Build.BRAND + "/" + Build.MODEL + "/" + Build.VERSION.RELEASE;
}
}
把这个拦截器加到Retrofit里面去
public class MusicModel implements IMusicModel {
@Override
public Retrofit getUrl(String path) {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(path)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
presenter
public class MusicPresenter {
Context context;
IMusicModel model;
IMusicView view;
List<MusicBean.SongListBean> list;
public MusicPresenter(Context context, IMusicView view) {
this.context = context;
this.view = view;
model = new MusicModel();
}
public void showdata(){
Retrofit rf = model.getUrl("http://tingapi.ting.baidu.com/");
MusicService ms = rf.create(MusicService.class);
ms.getda().enqueue(new Callback<MusicBean>() {
@Override
public void onResponse(Call<MusicBean> call, Response<MusicBean> response) {
MusicBean mb = response.body();
list = new ArrayList<MusicBean.SongListBean>();
list.addAll(mb.getSong_list());
Log.i("+++++list++++++", "onResponse: "+list.toString());
view.showData(list);
}
@Override
public void onFailure(Call<MusicBean> call, Throwable t) {
}
});
}
}
需要创建一个service接口
public interface MusicService {
@GET("v1/restserver/ting?method=baidu.ting.billboard.billList&type=1&size=20&offset=0")
Call<MusicBean> getda();
}
注解的方式
创建recyclerview适配器,创建子布局
public class MusicAdapter extends RecyclerView.Adapter<MusicAdapter.MyViewHolder> {
List<MusicBean.SongListBean> list;
Context context;
public MusicAdapter(List<MusicBean.SongListBean> list, Context context) {
this.list = list;
this.context = context;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.item,null);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv.setText(list.get(position).getTitle());
Uri uri = Uri.parse(list.get(position).getPic_small());
holder.iv.setImageURI(uri);
}
@Override
public int getItemCount() {
return list == null ? 0 : list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;
ImageView iv;
public MyViewHolder(View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv_title);
iv = itemView.findViewById(R.id.iv_title);
}
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/iv_title"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="哈哈哈哈哈哈哈哈哈"/>
</LinearLayout>
主方法调用,与presenter交互
public class MainActivity extends Activity implements IMusicView, View.OnClickListener {
private RecyclerView rv;
List<MusicBean.SongListBean> mlist;
private TextView mFTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
MusicPresenter presenter = new MusicPresenter(this, this);
presenter.showdata();
}
private void initView() {
rv = (RecyclerView) findViewById(R.id.rv);
mFTv = (TextView) findViewById(R.id.tv_f);
mFTv.setOnClickListener(this);
}
@Override
public void showData(List<MusicBean.SongListBean> bean) {
mlist = bean;
rv.setLayoutManager(new LinearLayoutManager(this));
MusicAdapter adapter = new MusicAdapter(mlist, this);
rv.setAdapter(adapter);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_f:
Tuichu();
break;
default:
break;
}
}
private void Tuichu() {
new AlertDialog.Builder(this)
.setTitle("确认")
.setMessage("确认要删除吗?")
.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
})
.setNegativeButton("否", null)
.show();
}
}